POJ2299逆序对模板(树状数组)

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

只能相邻两个交换,所以交换一次只会减少一个逆序对。所以交换次数就是逆序对数。

ps:原来树状数组还可以记录后边lowbit位的部分和。见代码。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500005
using namespace std;
int n,f[maxn];
long long tmp[maxn],a[maxn],sum;
void add(int k)
{
    while(k)
    {
        f[k]++;
        k-=k&-k;
    }
}
int query(int k)
{
    int ret=0;
    while(k<=n)
    {
        ret+=f[k];
        k+=k&-k;
    }
    return ret;
}
int main()
{
    while(1)
    {
        sum=0;
        memset(f,0,sizeof f);
        scanf("%d",&n);
        if(!n)return 0;
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]),tmp[i]=a[i];
        sort(tmp+1,tmp+n+1);
        unique(tmp+1,tmp+n+1);
        for(int i=1;i<=n;i++)
            a[i]=lower_bound(tmp+1,tmp+n+1,a[i])-tmp;
        for(int i=1;i<=n;i++)
        {
            sum+=query(a[i]);
            add(a[i]);
        }
        printf("%lld\n",sum);
    }
}

 

posted on 2018-02-28 16:50  Narh  阅读(60)  评论(0编辑  收藏

导航