训练指南 P197 例题
扫描一下所有的i,计算出从1到i-1有多少个数比它大,和从i+1到n有多少个数比它大。
然后就是交叉相乘算出总的方案数。
#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 120000
using namespace std;
long long a[21000];
long long l[21000],r[21000];
long long bit[120000];
long long lowbit(long long x)
{
return x&(-x);
}
bool add(long long x,long long v)
{
while (x <= INF)
{
bit[x]+=v;
x+=lowbit(x);
}
}
long long sum(long long x)
{
long long res;
res=0;
while (x > 0)
{
res+=bit[x];
x-=lowbit(x);
}
return res;
}
int main()
{
long long prob,i,n,j,ans;
scanf("%lld",&prob);
while (prob--)
{
scanf("%lld",&n);
for (i=1; i<=n; i++)
scanf("%lld",a+i);
memset(bit,0,sizeof(bit));
add(a[1],1);
for (i=2; i<=n; i++)
{
l[i]=sum(a[i]);
add(a[i],1);
}
memset(bit,0,sizeof(bit));
add(a[n],1);
for (i=n-1; i>=1; i--)
{
r[i]=(n-i)-sum(a[i]);
add(a[i],1);
}
ans=0;
for (i=1; i<=n; i++)
{
ans+=(i-1-l[i])*(n-i-r[i])+l[i]*r[i];
}
printf("%lld\n",ans);
}
}