题意:给定n个数,a1~an。ai代表每个人的能力值。举办乒乓比赛一次需要三个人,要求中间的人(裁判)的能力值大于其左边的人且小于其右边的人。求一共能举办多少场比赛。
分析:用s1[i]表示第i个人的左边有s1[i]个人的能力值小于ai,用s2[i]表示第i个人的右边有s2[i]个人的能力值小于ai。则以第i个人为裁判可以举办(s1[i]*(n-i-s2[i])+(i-1-s1[i])*s2[i])场比赛。
AC代码
#include <cstdio>
#include <cstring>
using namespace std;
#define lowbit(x) (x&-x)
#define maxn 1000000
typedef long long ll;
ll n,a[maxn],c[maxn],d[maxn],s1[maxn],s2[maxn],x[maxn];
ll sum(ll x)
{
ll res=0;
while(x>0)
{
res+=c[x];
x-=lowbit(x);
}
return res;
}
void add(ll x,ll d)
{
while(x<=100005)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(x,0,sizeof(x));
scanf("%lld",&n);
for(ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
memset(c,0,sizeof(c));
for(ll i=1;i<=n;i++)
{
add(a[i],1);
s1[i]=sum(a[i]-1);
}
memset(c,0,sizeof(c));
for(ll i=n;i>=1;i--)
{
add(a[i],1);
s2[i]=sum(a[i]-1);
}
ll ans=0;
for(ll i=2;i<=n;i++)
{
ans+=s1[i]*(n-i-s2[i])+(i-s1[i]-1)*s2[i];
}
printf("%lld\n",ans);
}
return 0;
}