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 }
View Code

 

posted @ 2013-10-24 18:45  Yours1103  阅读(168)  评论(0编辑  收藏  举报