一群乒乓爱好者组织比赛,给出一群乒乓爱好者的技能值,每场比赛需要两名选手和一名裁判。裁判必须在选手中间,并且技能值也在选手中间,问一共能组织多少种比赛?
选手的技能值:A1······Ai······An;
假设在A1到Ai内有c个选手的技能值比Ai小,即有(i-1-c)个选手的技能值比Ai大;
假设在Ai到An内有d个选手的技能值比Ai小,即有(n-i-d)个选手的技能值比Ai大;
所以,总共的方案个数:c*(n-i-d)+(i-1-c)*d;
代码如下:
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int N=200005;
int n;
long long tree[N];
int t;
int data[N];
long long pre[N];
long long sub[N];
int lowbit(int i)
{
return i&(-i);
}
void update(int i,int x)
{
while(i<=N)
{
tree[i]+=x;
i+=lowbit(i);
}
}
int query(int i)
{
int ans=0;
while(i>0)
{
ans+=tree[i];
i-=lowbit(i);
}
return ans;
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(tree,0,sizeof(tree));
memset(pre,0,sizeof(pre));
memset(sub,0,sizeof(sub));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&data[i]);
for(int i=1;i<=n;i++)
{
pre[i]=query(data[i]-1);
update(data[i],1);
}
memset(tree,0,sizeof(tree));
for(int i=n;i>=1;i--)
{
sub[i]=query(data[i]-1);
update(data[i],1);
}
long long ans=0;
for(int i=1;i<=n;i++)
{
long long c=pre[i];
long long d=sub[i];
ans+=c*(n-i-d)+(i-1-c)*d;
}
printf("%lld\n",ans);
}
return 0;
}