poj2299 树形数组&&离散化

来源:互联网 发布:angularjs php 跨域 编辑:程序博客网 时间:2024/06/05 19:50

参考了大牛的思路。。

首先 数字0-999999999,数量500000,如果按照常规思路会使用大量内存,因为题中我们只需要数字的大小关系,所以可以sort后根据顺序来进行数据的离散化,节省空间。

另外,用树状数组计算逆序数,所谓逆序数,即该数字后面比它小的数字的数量。在构建树状数组时,先插入数值小的元素。

下面是代码:

#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;int n;const int maxn=500010;struct Node{    int val,pos;}node[maxn];int c[maxn];int relax[maxn];int lowbit(int x){    return x&(-x);}ll get(int x){    int i;    ll sum=0;    for(i=x;i>0;i-=lowbit(i)){            //printf("%d\n",i);        sum+=c[i];    }    return sum;}void update(int x){    int i;    for(i=x;i<=n;i+=lowbit(i))    {        c[i]+=1;    }}bool cmp(const Node& a,const Node& b){    return a.val<b.val;}int main(){    while(~scanf("%d",&n)&&n)    {        int i;        for(i=1;i<=n;i++){            scanf("%d",&node[i].val);            node[i].pos=i;        }        sort(node+1,node+n+1,cmp);        for(i=1;i<=n;i++)        {            relax[node[i].pos]=i;            c[i]=0;        }        ll ans=0;        for(i=1;i<=n;i++)        {            update(relax[i]);            //printf("%d\n",relax[i]);            ans+=i-get(relax[i]);        }        printf("%I64d\n",ans);    }    return 0;}
就这样吧

0 0