逆序对数线段树数求法与树状数组求法

在数组a中a[i],a[j]是一个逆序对,当且仅当ia[j]时成立。

先考虑下暴力求法:

求以a[i]为大数的逆序对的个数,则我们检索0~i-1中大于a[i]的个数记入总数。

时间复杂度:n^2,复杂度很高。

现在我们考虑下,利用线段树的方法。

我们每拿到一个数我们就必须求出前面比这个数大的数的个数 k,于是我们可以用线段树记下区间数的个数,查询出这k就可以了,每次我们求完一个数的逆序对数就把这数放入线段树并经行维护。

当数非常大时,我们可以离散化下就可以了,以下代码是带有离散处理的。

code:

#include
#include
#include
#include
#define model l,mid,num<<1
#define moder mid+1,r,num<<1|1
using namespace std;
typedef long long LL;
int MAX;
const int M=1e5+5;
struct node{
    LL v;//记下数值。
    int x;//记下下标。
    node(){};
    node(LL vv,int xx){v=vv,x=xx;};
};
node record[M];
LL arr[M];
int n;
void poshash()
{
    sort(record+1,record+n+1,[](node a,node b){return a.vR)return 0;
    if(L<=l&&r<=R)
    {
        return pre[num];
    }
    int mid=(l+r)/2;
    if(R<=mid)return query(L,R,model);
    else if(mid>n)
    {
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&arr[i]);
            record[i]=node(arr[i],i);
        }
        poshash();
        memset(pre,0,sizeof(pre));
        int sum=0;
        for(int i=1;i<=n;++i)
        {
            sum+=query(arr[i]+1,MAX,1,MAX,1);
            update(arr[i],arr[i],1,1,MAX,1);
        }
        cout<

 

 

你可能感兴趣的:(数据结构)