动态逆序对 BIT套线段树

动态逆序对

Code


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define ll long long
using namespace std;
const int N=4e5;
const int M=3e7+100;
int root[M],sum[M],pos[N],lc[M],rc[M],A[M],B[M],b[N],a[N],c[N],tot=0,n,m,x;
ll ans=0;
int lowbit(int x){return x&-x;}
void add(int x,int v)
{while(x<=n)c[x]+=v,x+=lowbit(x);}
int ask(int x)
{int sum=0;while(x)sum+=c[x],x-=lowbit(x);return sum;}
void update(int &o,int L,int R,int x,int v){
    if(!o)o=++tot;
    int M=L+R>>1;
    sum[o]+=v;
    if(L==R)return;
    if(x<=M) update(lc[o],L,M,x,v);
    else update(rc[o],M+1,R,x,v);
}
int querymore(int l,int r,int L,int R,int v){
    int M=L+R>>1,tot=0;
    if(M+1>v){
        bool ok=0;
        for(int i=r;i;i-=lowbit(i))tot+=sum[rc[A[i]]];
        for(int i=l;i;i-=lowbit(i))tot-=sum[rc[B[i]]];
        for(int i=r;i;i-=lowbit(i))A[i]=lc[A[i]],ok|=A[i];
        for(int i=l;i;i-=lowbit(i))B[i]=lc[B[i]],ok|=B[i];
        
        if(ok) return querymore(l,r,L,M,v)+tot;
        return tot;
    }else{
        bool ok=0;
        for(int i=r;i;i-=lowbit(i))A[i]=rc[A[i]],ok|=A[i];
        for(int i=l;i;i-=lowbit(i))B[i]=rc[B[i]],ok|=B[i];
        if(ok) return querymore(l,r,M+1,R,v);
        return 0;
    }
}
int queryless(int l,int r,int L,int R,int v){
    int M=L+R>>1,tot=0;
    if(M<v){
        bool ok=0;
        for(int i=r;i;i-=lowbit(i))tot+=sum[lc[A[i]]];
        for(int i=l;i;i-=lowbit(i))tot-=sum[lc[B[i]]];
        for(int i=r;i;i-=lowbit(i))A[i]=rc[A[i]],ok|=A[i];
        for(int i=l;i;i-=lowbit(i))B[i]=rc[B[i]],ok|=B[i];
        if(ok) return queryless(l,r,M+1,R,v)+tot;
        return tot;
    }else{
        bool ok=0;
        for(int i=r;i;i-=lowbit(i))A[i]=lc[A[i]],ok|=A[i];
        for(int i=l;i;i-=lowbit(i))B[i]=lc[B[i]],ok|=B[i];
        if(ok) return queryless(l,r,L,M,v);
        return 0;
    }
}
void reset(int l,int r){
    for(int i=r;i;i-=lowbit(i))A[i]=root[i];
    for(int i=l;i;i-=lowbit(i))B[i]=root[i];
}
int main()
{
    //freopen("a.in","r",stdin);
    scanf("%d%d",&n,&m);
    rep(i,1,n){
        scanf("%d",&a[i]);
        pos[a[i]]=i;
    }
    rep(i,1,m) scanf("%d",&b[i]);
    rep(i,1,n){
        for(int x=i;x<=n;x+=lowbit(x))update(root[x],1,n,a[i],1);
        add(a[i],1); ans+=i-ask(a[i]);
    }
    rep(i,1,m){
        printf("%lld\n",ans);
        reset(0,pos[b[i]]-1);
        ans-=querymore(0,pos[b[i]]-1,1,n,b[i]);
        reset(pos[b[i]],n);
        ans-=queryless(pos[b[i]],n,1,n,b[i]);
        for(int x=pos[b[i]];x<=n;x+=lowbit(x))update(root[x],1,n,b[i],-1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/strangeDDDF/article/details/87877366