poj 2299

来源:互联网 发布:电脑声控软件 编辑:程序博客网 时间:2024/05/01 08:40

http://poj.org/problem?id=2299

其实就是求次序列的逆序数,但是这道题目要注意到,0 ≤ a[i] ≤ 999,999,999  ,用树状数组做的时候,开不了这么大的数组,但是 n < 500,000,我们可以用离散化的思想,用一个较小的范围的数组来解决数据量过大的问题。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include<algorithm>using namespace std;int b[500010],c[500010],d[500010],n,maxx;struct A{    int x,index;}a[500010];int cmp(A p1,A p2){    return p1.x < p2.x;}int lowbit(int x){    return x & (-x);}void update(int x,int y){    while(x <= n)    {        c[x] += y;        x += lowbit(x);    }}int getsum(int x){    int tmp = x;    int res = 0;    while(x > 0)    {        res += c[x];        x -= lowbit(x);    }    return res;}int main(){    while(~scanf("%d",&n),n)    {        memset(b,0,sizeof(b));        memset(c,0,sizeof(c));        memset(d,0,sizeof(d));        int i,j,num;        maxx = 0;        for(i = 1; i <= n;i++)// 离散化        {            scanf("%d",&a[i].x);            a[i].index = i;        }        sort(a+1,a+n+1,cmp);        for(i = 1; i <= n; i++)        b[a[i].index] = i;        for(i = 1; i <= n; i++)//getsum  函数求出的是 b[i] 前面出现的比他小的数的个数        {            d[i] = i-1 - getsum(b[i]);            update(b[i],1);        }        long long res = 0;        for(i = 1; i <= n; i++)// 求出所有的逆序数。注意有可能超出int          res += d[i];        printf("%I64d\n",res);    }    return 0;}


0 0
原创粉丝点击