LA 4329 - Ping pong 树状数组(Fenwick树)
哭瞎了,交上去一直 Runtime error 。以为那里错了。
狂改!!!!!
然后还是一直。。。
继续狂改!!!!。。。
一直。。。。
最后发现数组开小了。。。。。。。。。。
果断改了。。。。。AC了。。。。。。哭瞎了。。。。T T
笨蛋T T数组开太小这么愚蠢的错误也会犯!
笔记:
二叉索引树(也称Fenwick树)
对于节点i ,如果它是左子结点,父结点就是 i+ lowbit(i) 如果他是右结点, 父结点就是 i- lowbit(i)
C[i ]= A[ i -lowbit(i) +1] + A[ i -lowbit(i) +2] +……A [i]
#include<cstdio> #include<cstring> #include<algorithm> #include <iostream> using namespace std; const int MAXN=20000+10; const int MAXA=100000+10; int N; int C[MAXA]; //这里存的是a必须大于a的最大值。一开始直接MAXN杯具 inline int lowbit(int x) { return x&(-x) ; } int sum(int x) { int ans=0; while(x>0) { ans+=C[x]; x-=lowbit(x); } return ans; } void add(int x,int d) { while(x<=N) { C[x]+=d; x+=lowbit(x); } } int a[MAXN],c[MAXN],d[MAXN]; int main() { int T; scanf("%d",&T); while(T--) { int n,m=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); m=max(m,a[i]); } N=m; memset(C,0,sizeof(C)); for(int i=1;i<=n;i++) { add(a[i],1); c[i]=sum(a[i]-1); } memset(C,0,sizeof(C)); for(int i=n;i>=1;i--) { add(a[i],1); d[i]=sum(a[i]-1); } long long ans=0; for(int i=1;i<=n;i++) ans=ans+ (long long)c[i]*(n-i-d[i]) + (long long)(i-c[i]-1)*d[i]; printf("%lld\n", ans); } return 0; }
新 blog : www.hrwhisper.me