题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5147
解题思路:BestCoder官方题解:
要统计四元组的数量我们可以通过枚举c,然后统计区间[1,c-1]有多少二元组(a,b)满足a < b且 Aa<Ab ,以及统计出区间[c+1,n]有多少d满足 Ac<Ad ,根据乘法原理,把这两项乘起来就可以统计到答案里了. 然后我们来处理子问题:区间[1,c-1]内有多少二元组(a,b).那么我们可以枚举b,然后统计区间[1,b-1]内有多少a满足 Aa<Ab ,那么这个可以通过用树状数组询问前缀和来实现. 时间复杂度是O(nlogn).AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef __int64 ll;
int a[50010];
int n;
int lowbit(int x)
{
return x&(-x);
}
int getsum(int x)
{
int sum=0;
while(x)
{
sum+=a[x];
x-=lowbit(x);
}
return sum;
}
void add(int x)
{
while(x<=n)
{
a[x]++;
x+=lowbit(x);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,m;
ll pre=0,ans=0;
memset(a,0,sizeof(a));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&m);
int t=getsum(m);
int k=n-m-(i-t-1);//后面比m大的数字
ans+=k*pre;
pre+=t;
add(m);
}
printf("%I64d\n",ans);
}
return 0;
}