Codeforces961E Tufurama
题意:输入一个序列,查询满足条件的(x, y)点对使得a[x]>=y&&a[y]>=x&&x<y
题解:枚举y,对于每一个y,找到小于y的数x并且a[x]>=y的个数的和,可以用树状数组维护一下,从大到小更新,每次更新后求前缀
#include <bits/stdc++.h> #define maxn 200010 #define INF 0x3f3f3f3f using namespace std; int c[maxn], n, a[maxn]; long long ans; vector<int >G[maxn]; int query(int x){ int sum = 0; for(int i=x;i>=1;i-=i&(-i)) sum += c[i]; return sum; } void update(int x){ for(int i=x;i<=n;i+=i&(-i)) c[i]++; } int main(){ scanf("%d", &n); for(int i=1;i<=n;i++){ scanf("%d", &a[i]); if(a[i]>n) G[n].push_back(i); else G[a[i]].push_back(i); } for(int i=n;i>=1;i--){ for(auto j:G[i]) update(j); ans += query(min(a[i], i-1)); } cout<<ans<<endl; return 0; }
posted on 2018-04-07 19:44 2855669158 阅读(169) 评论(0) 编辑 收藏 举报