n个人,从左到右排列,每个人都有一个不一样技能值 arr[i], 每场比赛3个人: 两名选手, 一名裁判。 裁判必须在两名选手中间, 并且技能值也在两名选手之间, 问一共能组织多少种比赛。
树状数组的基本应用。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define maxn 100010
using namespace std;
LL left[maxn],c[maxn],arr[maxn];
int lowbit(int x)
{
return x&(-x);
}
LL sum(int i)
{
LL sum=0;
while(i>0)
{
sum+=c[i];
i-=lowbit(i);
}
return sum;
}
void add(int i,LL x)
{
while(i<maxn)
{
c[i]+=x;
i+=lowbit(i);
}
}
int main()
{
int cas,n;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
memset(c,0,sizeof(c));
for(int i=0; i<n; i++)
{
scanf("%d",&arr[i]);
left[i]=0;
}
for(int i=0; i<n; i++)
{
left[i]=sum(arr[i]);
add(arr[i],1);
}
LL ans = 0;
memset(c,0,sizeof(c));
for(int i=n-1; i>=0; i--)
{
LL d=sum(arr[i]);
add(arr[i],1);
ans+=(left[i]*(n-i-1-d)+d*(LL)((LL)i-left[i]));
}
printf("%lld\n",ans);
}
return 0;
}