The tree number calculation method and tree array calculation method of reverse order logarithmic line segment

Posted by CodeWriter on Wed, 01 Jan 2020 18:07:35 +0100

In array a, a[i],a[j] is a reverse order pair, if and only if I < J and a [i] > a [J].

First of all, consider the following violent methods:

To find the number of reverse pairs with a[i] as the large number, we retrieve the number greater than a[i] in 0~i-1 and record it in the total number.

Time complexity: n^2, high complexity.

Now let's consider using the line tree method.

Every time we get a number, we have to find the number k that is larger than this number. So we can use the line tree to record the number of intervals, and find out the K. every time we find the reverse logarithm of a number, we put the number into the line tree and maintain it.

When the number is very large, we can discretize it. The following code is discrete.

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#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;//Write down the values.
    int x;//Write down the subscript.
    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.v<b.v;});
    MAX=1;
    for(int i=1;i<=n;++i)
    {
        if(record[i].v!=record[i-1].v&&i!=1)MAX++;
        arr[record[i].x]=MAX;
    }
    return ;
}
int pre[M<<2];
int query(int L,int R,int l,int r,int num)
{
    if(L>R)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<L)return query(L,R,moder);
    else if(L<=mid&&mid<R)return query(L,R,model)+query(L,R,moder);
}
void update(int L,int R,int key,int l,int r,int num)
{
    if(L<=l&&r<=R)
    {
        pre[num]+=key;
        return ;
    }
    int mid=(l+r)/2;
    if(mid<L)update(L,R,key,moder);
    else if(R<=mid)update(L,R,key,model);
    else if(L<=mid&&mid<R)
    {
        update(L,R,key,model);
        update(L,R,key,moder);
    }
    pre[num]=pre[num<<1]+pre[num<<1|1];
}
int main()
{
    while(cin>>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<<sum<<endl;
    }
}