UVA 1428 Ping pong

树状数组

枚举裁判位置,设裁判为第i 个人,左边有l[i]个比他小的选手,右边有r[i]个比他小的选手;

令c[i]表示技能值为i 的人是否存在,计算l[i] 即c[1]~c[i-1]的和,计算l[i]后使c[a[i]]=1;同理求r[i];

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int maxn = 100005;
 7 
 8 int n;
 9 int a[maxn];
10 long long c[maxn];
11 long long l[maxn],r[maxn];
12 
13 int lowbit (int x){
14     return x&(-x);
15 }
16 
17 void add (int x,long long d){
18     while (x<=maxn-5){  //这里是我坑了很久的地方。。。这里的边界是技能值边界。。。
19         c[x]+=d;
20         x+=lowbit(x);
21     }
22 }
23 
24 long long sum (int x){
25     long long ans=0;
26     while (x>0){
27         ans+=c[x];
28         x-=lowbit(x);
29     }
30     return ans;
31 }
32 
33 int main (){
34     int t;    //while (cin>>t) cout<<lowbit(t)<<endl;
35     cin>>t;
36     while (t--){
37         cin>>n;
38         for (int i=1;i<=n;i++){
39             cin>>a[i];
40         }
41         memset (c,0,sizeof c);
42         for (int i=1;i<=n;i++){
43             l[i]=sum(a[i]);
44             add (a[i],1);
45         }
46         memset (c,0,sizeof c);
47         for (int i=n;i>=1;i--){
48             r[i]=sum(a[i]);
49             add (a[i],1);
50         }
51         long long ans=0;
52         for (int i=1;i<=n;i++)
53             ans+=l[i]*(n-i-r[i])+(i-l[i]-1)*r[i];//cout<<l[i]<<" "<<r[i]<<endl;
54         cout<<ans<<endl;
55     }
56     return 0;
57 }
原文地址:https://www.cnblogs.com/gfc-g/p/3890493.html