题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4000
题意大致为:给一个1-n的序列,求有序数对(x,y,z)其中x<z<y出现的次数。
通过树状数组可以得到a[i]的后面含有的大于a[i]的数的个数,假设个数为high,那么有序数对(x,y,z)其中(x<y,x<z,y?z)的个数显然为C(n,2)然后我们在丛中减去x<y<z的数对的个数,即可得到x<z<y的个数
对于一个数y,x<y<z的个数为y前面比它小的数的个数n*y后面比它大的数的个数
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define MOD 100000007
int n;
long long a[100005];
int c[100005];
int lowbit(int x)
{
return x&(x^(x-1));
}
int getsum(int x)
{
int sum=0;
while (x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update(int x,int s)
{
while (x<=n)
{
c[x]+=s;
x+=lowbit(x);
}
}
int main()
{
int t;
int cot=0;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (int i=0;i<n;i++)
{
scanf("%I64d",&a[i]);
}
memset(c,0,sizeof(c));
long long ans=0;
for (int i=0;i<n;i++)
{
long long x=getsum(a[i]);
update(a[i],1);
long long high=n-i-a[i]+x;
ans=(ans-x*high+high*(high-1)/2)%MOD;
while (ans<0) ans+=MOD;
}
printf("Case #%d: %I64d\n",++cot,ans);
}
return 0;
}