N (3N
20000)
Input
The first line of the input contains an integer T (1T
20) , indicating the number of test cases, followed by T
Every test case consists of N + 1 integers. The first integer is N , the number of players. Then N distinct integers a1, a2...aN follow, indicating the skill rank of each player, in the order of west to east ( 1ai
100000 , i = 1...N
Output
For each test case, output a single line contains an integer, the total number of different games.
Sample Input
1
3 1 2 3
Sample Output
1
思路:第i个为裁判,则有ci为左边比i小的,di为右边比i大的。ci*(n-i-di)+di*(i-1-ci)
结果就是它们的和。
ci.di咋求呢?第i个的值当位置来加就好了。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int mn=1e5+9;
const int mm=2e4+9;
long long sum[mn];
long long hh[mm],tt[mm];
long long f[mm];
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
for(int i=x;i<mn;i+=lowbit(i))
{
sum[i]++;
}
}
int query(int x)
{ int ret=0;
for(int i=x;i>0;i-=lowbit(i))
{
ret+=sum[i];
}
return ret;
}
int main()
{
int cas,n;
while(~scanf("%d",&cas))
{
while(cas--)
{ memset(sum,0,sizeof(sum));
scanf("%d",&n);
int a;
for(int i=0;i<n;++i)
{
scanf("%d",&f[i]);
}
long long ans=0;
for(int i=0;i<n;++i)
{
hh[i+1]=query(f[i]);
update(f[i]);
}
memset(sum,0,sizeof(sum));
for(int i=n-1;i>=0;--i)
{
tt[i+1]=query(f[i]);
update(f[i]);
}
for(int i=1;i<=n;++i)
ans+=hh[i]*((long long)(n-i-tt[i]))+(i-hh[i]-1)*(tt[i]);
printf("%lld\n",ans);
}
}
return 0;
}