poj 2299 离散化+树状数组求逆序数

传送门

题意:求逆序数。

思路:500000个数,n*n的朴素求法显然不行,数状数组吧,可是数字可达近10亿,这么大的数组开不了,就先离散化一下吧,这样就好啦。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int a,b,id;
}p[500005];
int n,c[500005];
long long int ans;
bool cmp1(node x,node y)
{
    return x.a<y.a;
}
bool cmp2(node x,node y)
{
    return x.id<y.id;
}
void add(int x)
{
    for(int i=x;i<=500000;i+=(i&(-i)))
    {
        c[i]++;
    }
}
int sum(int x)
{
    int s=0;
    for(int i=x;i>0;i-=(i&(-i)))
    {
        s+=c[i];
    }
    return s;
}
int main()
{
    while(scanf("%d",&n)&&n)
    {
        memset(c,0,sizeof(c));
        ans=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&p[i].a);
            p[i].id=i;
        }
        sort(p,p+n,cmp1);
        p[0].b=1;
        int num=1;
        for(int i=1;i<n;i++)
        {
            if(p[i].a==p[i-1].a)p[i].b=num;
            else p[i].b=++num;
        }
        sort(p,p+n,cmp2);
        for(int i=0;i<n;i++)
        {
            ans+=(i-sum(p[i].b));
            add(p[i].b);
        }
        cout<<ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(poj,Baoge)