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