您的位置:首页 > 其它

hdu 4000 树状数组

2016-07-13 20:44 302 查看
   题目链接: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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: