Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3518 Accepted Submission(s): 1299
本题是2008年北京赛区的H题,大致题意为两个乒乓选手a和b想提升排名,但是通过比赛来提升自己的名次,于是他们找来一个同样也是乒乓选手的c作为裁判来抉择,
题目规定c必须在a和b之间,问对于所有的n个人,总共有多少中不同的可能....
思路:如果改变a和b,那么需要三个循环才能解决,显然会超时...
但是考虑c然后统计出小于c的有多少种可能x,大于c有多少种可能y..
很容易知道结果为x*y....
于是就可以推得公式: sum=Σi=0(xi*yi);
剩下的便是统计了...
这里我用的是BIT即树状数组
代码如下:
1 //@coder Gxjun 2 //BIT algorithm 3 #include<stdio.h> 4 #include<string.h> 5 #include<stdlib.h> 6 #define maxn 20000 7 #define val 100000 8 int bb[val+5],aa[maxn]; 9 //低位技术 10 int lowbit(int k) 11 { 12 return k&(-k); 13 // return k&(k&(k-1)); 14 // return k&!(k-1); 15 } 16 void ope(int x) 17 { 18 while(x<=val) 19 { 20 bb[x]++; 21 x+=lowbit(x); 22 } 23 } 24 25 int sum(int x) 26 { 27 int ans=0; 28 while(x>0) 29 { 30 ans+=bb[x]; 31 x-=lowbit(x); 32 } 33 return ans; 34 } 35 int xx[maxn],yy[maxn]; 36 int main() 37 { 38 int tt,nn,i; 39 scanf("%d",&tt); 40 while(tt--) 41 { 42 scanf("%d",&nn); 43 for(i=0;i<nn;i++) 44 scanf("%d",&aa[i]); 45 //求小于aa[i] 的个数在aa[0]~~aa[i-1] 46 memset(bb,0,sizeof(bb)); 47 for(i=0;i<nn;i++) 48 { 49 xx[i]=sum(aa[i]-1); 50 ope(aa[i]); 51 } 52 memset(bb,0,sizeof(bb)); 53 for(i=nn-1; i>=0;i--) 54 { 55 yy[i]=sum(aa[i]-1); 56 ope(aa[i]); 57 } 58 __int64 res=0; 59 for(i=0;i<nn ;i++) 60 { 61 res+=(i-xx[i])*yy[i]+xx[i]*(nn-i-1-yy[i]); 62 } 63 printf("%I64d\n",res); 64 } 65 return 0; 66 }