逆序对+离散树状数组....

求逆序对有三种以上方法:1、离散树状数组,2、线段树,3、归并排序

今天做了下洛谷的P1908逆序对;

1、一开始用树状数组,一直RE,后来在发现自己一直忽略离散化。

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 400000+5;
typedef long long ll;
ll n,Hash[maxn],bt[maxn];
struct node {
    int v,id;
}a[maxn];
ll lowbit(ll x)
{
    return (x)&(-x);
}

void add(ll i,ll b)
{
    while(i<=n)
    {
        bt[i]+=b;
        i+=lowbit(i);
    }
}

ll qu(ll i)
{
    ll ans=0;
    while(i>0)
    {
        ans+=bt[i];
        i-=lowbit(i);
    }
    return ans;
}
bool cmp(node a,node b)
{
    return a.v<b.v;
}
int main(){
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i].v;
        a[i].id=i;
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        Hash[a[i].id]=i;
    }
    //离散化结束;
    ll sum = 0;
    for(int i=1;i<=n;i++)
    {
        sum+=(i-1-qu(Hash[i])); //当前树状数组中有i-1个,quary(a[i])前缀和查出a[i]前的个数
        add(Hash[i],1);          //值为a[i]的数又增加了一个
    }
    cout<<sum<<endl;
    return 0;
}

 

posted @ 2018-02-26 21:26  ckxkexing  阅读(94)  评论(0编辑  收藏  举报