Codeforces

题意:

  一个剧一共有n季,每季有ai集。问有多少对x,y(x≠y),使得第x季有第y集且第y季有第x集。

题解:

  用set维护第i季的“寿命”,用树状数组维护第i季前有多少季还有第i集。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
typedef long long ll;
int n;
int tmp;
ll ans;
int tree[maxn];
set<pair<int, int> > st; 
void add(int x, int v) {
    while(x <= n) {
        tree[x] += v;
        x += x&(-x);
    }
}
int sum(int x) {
    int res = 0;
    while(x > 0) {
        res += tree[x];
        x -= x&(-x);
    }
    return res;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &tmp);
        ans += sum(min(i-1, tmp));
        
        while(!st.empty() && st.begin()->first==i) {
            add(st.begin()->second, -1);
            st.erase(st.begin());
        }
        if(tmp > i) {
            add(i, 1);
            st.insert(make_pair(tmp, i));
        }
    }
    printf("%lld
", ans);
}
View Code
原文地址:https://www.cnblogs.com/Pneuis/p/8727723.html