看了这道题感觉自己收获很大,这道题的思路就很奇葩,一般人不容易想到。对于第i个人,只要遍历出从1到i-1技能比他小的人ci,从i+1到n遍历出技能比他小的人di,那么对于技能为ai的人来说,可以组织比赛ci*(n-i-di)+di*(i-1-ci);这里的ci,di通过树状数组可以得到。通过吧1到i-1的技能添加到ci中,可以统计出比ai小的技能的总数,同理di也是这样。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#define MA 100010
using namespace std;
long long x[MA],a[20010],c[MA],d[MA];
int lowbit(int x) {
return x&(-x);
}
void add(int a) {
while(a<MA) {
x[a]+=1;
a+=(lowbit(a));
}
}
int sum(int a) {
int ans=0;
while(a>0) {
ans+=x[a];
a-=lowbit(a);
}
return ans;
}
int main() {
int n,i,m;
long long ans=0;
cin>>n;
while(n--) {
memset(x,0,sizeof(x));
cin>>m;
ans=0;
for(i=1; i<=m; i++) {
cin>>a[i];
add(a[i]);
c[i] = sum(a[i]-1);
}
memset(x,0,sizeof(x));
for(i=m; i>0; i++) {
add(a[i]);
d[i] = sum(a[i]-1);
}
for(i=2; i<m; i++) ans+=c[i]*(m-i-d[i])+d[i]*(i-1-c[i]);
cout<<ans<<endl;
}
return 0;
}