uva 1428 - Ping pong
树状数组,把他们的技能值作为轴;
首先按照编号从小到大插入值,这样就可以得到,技能值比当前小的人数;
然后按照编号从大到小再插一遍;
代码:
1 #include<cstdio> 2 #include<cstring> 3 #define maxn 20005 4 using namespace std; 5 6 int a[maxn],c[100010]; 7 int l[maxn],r[maxn]; 8 int lowbit(int x){return x&-x;} 9 void add(int x,int d){while(x<=100000){c[x]+=d,x+=lowbit(x);}} 10 int sum(int x) 11 { 12 int ret=0; 13 while(x>0){ret+=c[x],x-=lowbit(x);} 14 return ret; 15 } 16 17 int main() 18 { 19 int t,n; 20 scanf("%d",&t); 21 while(t--) 22 { 23 memset(c,0,sizeof c); 24 memset(l,0,sizeof l); 25 memset(r,0,sizeof r); 26 scanf("%d",&n); 27 for(int i=1;i<=n;i++) 28 { 29 scanf("%d",&a[i]); 30 add(a[i],1); 31 l[i]=sum(a[i]-1); 32 } 33 memset(c,0,sizeof c); 34 for(int i=n;i>=1;i--) 35 { 36 add(a[i],1); 37 r[i]=sum(a[i]-1); 38 } 39 long long ans=0; 40 for(int i=2;i<=n;i++) 41 ans+=l[i]*(n-i-r[i])+(i-l[i]-1)*r[i]; 42 printf("%lld\n",ans); 43 } 44 }