poj 3928

通过枚举每个点,也就是枚举可能的每个教练,得到在他之前的比他小的数的个数,比他大的数的个数,他之后的比他小的数的个数,比他大的数的数的个数,这个过程可通过树状数组等手段进行优化

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #define LL long long
 5 using namespace std;
 6 const int maxn=20000+10;
 7 const int maxm=100000;
 8 int n,a[maxn],sm1[maxn],sm2[maxn];
 9 LL c[maxm+10];
10 int lowbit(int x)
11 {
12     return x&(-x);
13 }
14 void update(int x,int v)
15 {
16     while(x<=maxm)
17     {
18         c[x]+=v;
19         x+=lowbit(x);
20     }
21 }
22 LL query(int x)
23 {
24     LL sum=0;
25     while(x)
26     {
27         sum+=c[x];
28         x-=lowbit(x);
29     }
30     return sum;
31 }
32 int main()
33 {
34     int t;
35     cin>>t;
36     while(t--)
37     {
38         scanf("%d",&n);
39         int i;
40         memset(c,0,sizeof(c));
41         for(i=1;i<=n;i++)
42             scanf("%d",&a[i]);
43         for(i=1;i<=n;i++)
44         {
45             sm1[i]=query(a[i]);
46             update(a[i],1);
47         }
48         memset(c,0,sizeof(c));
49         for(i=n;i>=1;i--)
50         {
51             sm2[i]=query(a[i]);
52             update(a[i],1);
53         }
54         LL sum=0;
55         for(i=1;i<=n;i++) sum=sum+sm1[i]*(n-i-sm2[i])+(i-1-sm1[i])*sm2[i];
56         printf("%I64d\n",sum);
57     }
58     return 0;
59 }

 

 

posted @ 2013-05-21 14:59  LJ_COME!!!!!  阅读(127)  评论(0编辑  收藏  举报