poj 2299 树状数组

来源:互联网 发布:快递单数据录入员兼职 编辑:程序博客网 时间:2024/06/16 01:49

题目链接:http://poj.org/problem?id=2299

题目大意:本题要用到树状数组的离散化处理,因为数据太大(1-999999999),但还是WA了两次,c[i]的范围计算错误,要用到long long .

               从后向前处理,每次处理一个数,求比这个数小的个数。

//poj 2299 树状数组#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;#define M 500010int a[M];long long c[M];int m;struct node{    int data;    int pos;}s[M];bool cmp(node x,node y){    return x.data<y.data;}int lowbit(int x){    return x&(-x);}void add(int k,int detal){    while(k<=m)    {        c[k]+=detal;        k+=lowbit(k);    }}int sum(int k){    int t=0;    while(k>0)    {        t+=c[k];        k-=lowbit(k);    }    return t;}int main(){    int n;    int i,j;    while(cin>>n)    {        if(n==0)            break;    for(i=1;i<=n;i++)  //离散化    {        scanf("%d",&s[i].data);        s[i].pos=i;    }    sort(s+1,s+n+1,cmp);    int k=0;    a[s[1].pos]=1;    m=1;    for(i=2;i<=n;i++)    {        if(s[i].data==s[i-1].data)            a[s[i].pos]=a[s[i-1].pos];        else            a[s[i].pos]=a[s[i-1].pos]+1;        if(m<a[s[i].pos])            m=a[s[i].pos];    }   //离散化完成    memset(c,0,sizeof(c));    long long ans=0;    for(i=n;i>=1;i--)    {        ans+=sum(a[i]-1);        add(a[i],1);    }    printf("%lld\n",ans);    }    return 0;}