• [CQOI2011]动态逆序对


    带修主席树。
    脑补一下,每个数对逆序对数的贡献就是前面的比它大的加上后面的比它小的,这样就可以套带修主席树的板子,找一下在它前面删去的比它大的,找一下在它后面比它小的数的个数就行了。
    UPD:BZOJ上T了,发现t[]开的太大了,memset的时候直接挂。。。认真算空间Orz

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=100005;
    int n,m,a[N],t[N*10],f[N],pos[N],g[N],x[N],y[N],rt[N];
    long long ans;
    void add(int x) {
        for(int i=x;i<=n;i+=i&-i) t[i]++;
    }
    int ask(int x) {
        int ans=0;  
        for(int i=x;i;i-=i&-i) ans+=t[i];
        return ans;
    }
    int tot,ls[N*100],rs[N*100],siz[N*100];
    void update(int &k,int l,int r,int val) {
        if(!k)k=++tot;siz[k]++;
        int mid=l+r>>1;
        if(l==r) return;
        if(val<=mid) update(ls[k],l,mid,val);
        else update(rs[k],mid+1,r,val);
    }
    int queryx(int L,int R,int val) {
        int totx=0,toty=0,ans=0;L--;
        int l=1,r=n;
        for(int i=L;i;i-=i&-i) x[++totx]=rt[i];
        for(int i=R;i;i-=i&-i) y[++toty]=rt[i];
        while(l!=r) {
            int mid=l+r>>1;
            if(val<=mid) {
                for(int i=1;i<=totx;i++) ans-=siz[rs[x[i]]],x[i]=ls[x[i]];
                for(int i=1;i<=toty;i++) ans+=siz[rs[y[i]]],y[i]=ls[y[i]];
                r=mid;
            }
            else {
                for(int i=1;i<=totx;i++) x[i]=rs[x[i]];
                for(int i=1;i<=toty;i++) y[i]=rs[y[i]];
                l=mid+1;
            }
        } 
        return ans;
    }
    int queryd(int L,int R,int val) {
        int totx=0,toty=0,ans=0;L--;
        int l=1,r=n;
        for(int i=L;i;i-=i&-i) x[++totx]=rt[i];
        for(int i=R;i;i-=i&-i) y[++toty]=rt[i];
        while(l!=r) {
            int mid=l+r>>1;
            if(val>mid) {
                for(int i=1;i<=totx;i++) ans-=siz[ls[x[i]]],x[i]=rs[x[i]];
                for(int i=1;i<=toty;i++) ans+=siz[ls[y[i]]],y[i]=rs[y[i]];
                l=mid+1;
            }
            else {
                for(int i=1;i<=totx;i++) x[i]=ls[x[i]];
                for(int i=1;i<=toty;i++) y[i]=ls[y[i]];
                r=mid;
            }
        }
        return ans;
    }
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),f[i]=ask(n)-ask(a[i]),add(a[i]),ans+=f[i],pos[a[i]]=i;
        memset(t,0,sizeof t);
        for(int i=n;i;i--) {
            g[i]=ask(a[i]);
            add(a[i]);
        }
        int u;
        for(int i=1;i<=m;i++) {
            printf("%lld
    ",ans);
            scanf("%d",&u);
            u=pos[u];
            ans-=(f[u]+g[u]-queryx(1,u-1,a[u])-queryd(u+1,n,a[u]));
            for(int j=u;j<=n;j+=j&-j) update(rt[j],1,n,a[u]);
        }
        return 0;
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    nyoj 17 单调递增最长子序列
    nyoj 18 The Triangle
    nyoj 712 探 寻 宝 藏
    nyoj 61传纸条(一)
    nyoj 269 VF
    nyoj 44 子串和
    nyoj 252 01串
    nyoj 42 一笔画问题
    nyoj 756 重建二叉树
    Table 样式设置
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9502630.html
Copyright © 2020-2023  润新知