您的位置:首页 > 其它

【HDU 4000】 树状数组

2012-11-07 23:25 381 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4000

题目大意:给出n个数,求(x<z<y)的次数 。(x,y,z一次先后出现)

解题思路:

题目数据量很大,暴力肯定不行的。

设现在出现的位置为x,后面比它大的数有s个。s个选两个(y,z)有s*(s-1)/2种。此时yz无序。

然后按题目要求x<z<y,所以还要把x<y<z除掉。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int maxn=100005;
const int mod=100000007;
int bit[maxn];
int  n;

int lowbit(int x)
{
return x&(-x);
}

void add(int x, int val)
{
while(x<=n)
{
bit[x]+=val;
x+=lowbit(x);
}
}

int sum(int x)
{
int cnt=0;
while(x>0)
{
cnt+=bit[x];
x-=lowbit(x);
}
return cnt;
}

int main()
{
int  T, tcase=0, tmp1, tmp2, a;
cin >> T;
while(T--)
{
cin >> n;
__int64 ans=0;
memset(bit,0,sizeof(bit));
for(int i=1; i<=n; i++)
{
scanf("%d",&a);
add(a,1);
tmp1=sum(a-1);     //a前面比a小的数的个数
tmp2=n-a-(i-tmp1-1);  //a后面比a大的数的个数
ans-=tmp1*tmp2;    //减去x<y<z这种情况
if(tmp2>=2)
ans+=tmp2*(tmp2-1)/2;
}
printf("Case #%d: %d\n",++tcase,ans%mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: