Ping pong(hdu 2492 树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2492
树状数组分别从前往后 从后往前 找比当前位置的值 小的个数
贴一个别人写的树状数组的博客:https://www.cnblogs.com/acgoto/p/8583952.html 还是很详细的
代码:
#include<bits/stdc++.h> using namespace std; #define LL long long const LL N = 100005; LL mp[N],n,tree[N],c[N],d[N]; LL lowbit(LL x) { return x&(-x); } LL sum(LL x) { LL ans = 0; while(x>0) { ans+=tree[x]; x-=lowbit(x); } return ans; } void add(LL x) { while(x<N) { tree[x]+=1; x+=lowbit(x); } } int main() { int T,i,j; scanf("%d",&T); while(T--) { cin>>n; for(i=0;i<n;i++) { scanf("%lld",&mp[i]); } for(i=0;i<N;i++)tree[i]=0; for(i=0;i<n;i++) { c[i]=sum(mp[i]);add(mp[i]);//前面有多少人比它小 } for(i=0;i<N;i++)tree[i]=0; for(j=n-1;j>=0;j--) { d[j]=sum(mp[j]);add(mp[j]);//后面有多少人比它小 } LL ans=0; for(i=0;i<n;i++) { ans+=c[i]*(n-i-d[i]-1)+(i-c[i])*d[i]; // n-i-d[i]-1:后面比他大的个数 i-c[i]:前面比他大的个数 } printf("%lld\n",ans); } return 0; }