• bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)


    Description

    对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

    Input

    输入第一行包含两个整数nm,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。
     

    Output

     
    输出包含m行,依次为删除每个元素之前,逆序对的个数。

    Sample Input

    5 4
    1
    5
    3
    4
    2
    5
    1
    4
    2

    Sample Output

    5
    2
    2
    1
     
    各种方法都可做
     
    树套树(5.9s)
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    int n,m,l,r,o,p,num=0;
    long long ans=0;
    inline int read(){
        p=0;o=getchar();
        while(o<'0'||o>'9') o=getchar();
        while(o>='0'&&o<='9') p=p*10+o-48,o=getchar();
        return p;
    }
    int root[100001],a[100001],tt[100001];
    struct tree{
        int l,r,k;
        tree(){
            k=0;
        }
    };
    tree t[10000000];
    inline void insert(int &p,int l,int r,int k){
        if (p==0) p=++num;
        t[p].k++;
        if (l==r) return;
        int mid=l+r>>1;
        if (k<=mid) insert(t[p].l,l,mid,k);else insert(t[p].r,mid+1,r,k);
    }
    inline void del(int p,int l,int r,int k){
        t[p].k--;
        if (l==r) return;
        int mid=l+r>>1;
        if (k<=mid) del(t[p].l,l,mid,k);else del(t[p].r,mid+1,r,k);
    }
    inline int qui(int p,int l,int r,int k){
        if (p==0) return 0;
        if (r==k) return t[p].k;
        int mid=l+r>>1;
        if (k<=mid) return qui(t[p].l,l,mid,k);else return qui(t[p].r,mid+1,r,k)+(t[p].l==0?0:t[t[p].l].k);
    }
    inline int qua(int p,int l,int r,int k){
        if (p==0) return 0;
        if (l==k) return t[p].k;
        int mid=l+r>>1;
        if (k<=mid) return qua(t[p].l,l,mid,k)+(t[p].r==0?0:t[t[p].r].k);else return qua(t[p].r,mid+1,r,k);
    }
    inline int lo(int x){return x&(-x);}
    inline void in(int i,int k){
        while(i<=n){
            insert(root[i],1,n,k);
            i+=lo(i);
        }
    }
    inline void de(int i,int k){
        while(i<=n){
            del(root[i],1,n,k);
            i+=lo(i);
        }
    }
    inline long long ask(int x,int k){
        long long s=0;
        k++;
        while(x>0){
            if (k<=n) s+=qua(root[x],1,n,k);
            x-=lo(x);
        }
        return s;
    }
    inline long long aski(int x,int k){
        long long s=0;
        k--;
        while(x>0){
            if (k>=1) s+=qui(root[x],1,n,k);
            x-=lo(x);
        }
        return s;
    }
    int main(){
        register int i,j;
        n=read();
        m=read();
        for (i=1;i<=n;i++) in(i,a[i]=read()),tt[a[i]]=i;
        for (i=1;i<=n;i++) ans+=ask(i,a[i]);
        while(m--){
            printf("%lld
    ",ans);
            l=read();r=tt[l];
            if (a[r]==0) continue;a[r]=0;
            ans-=ask(r,l)+aski(n,l)-aski(r,l);
            de(r,l);
        }
    }
    View Code

    CDQ分治

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int read_p,read_ca,pr_num,pr_ch[1000];
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    inline void pr(long long k){
        pr_num=0;
        while(k>0) pr_ch[++pr_num]=k%10,k/=10;
        while(pr_num)
        putchar(pr_ch[pr_num--]+48);
        putchar('
    ');
    }
    struct na{
        int x,y,t;
    }b[100001],o[100001],y[100001];
    int n,m,u[100001],ti[100001],s[100001];
    long long ans[100001][2];
    inline int low(int x){return x&(-x);}
    
    inline void add(int x){
        while (x<=n){
            s[x]++;
            x+=low(x);
        }
    }
    inline void del(int x){
        while (x<=n){
            s[x]--;
            x+=low(x);
        }
    }
    inline int ask(int x){
        int ans=0;
        while (x>0){
            ans+=s[x];
            x-=low(x);
        }
        return ans;
    }
    inline bool cmp(na a,na b){
        if ((a.x==b.x)&&(a.y==b.y)) return a.t<b.t;
        if (a.x==b.x) return a.y>b.y;
        return a.x<b.x;
    }
    inline bool tmp(na a,na b){
        if ((a.x==b.x)&&(a.y==b.y)) return a.t<b.t;
        if (a.x==b.x) return a.y<b.y;
        return a.x>b.x;
    }
    inline void work0(int l,int r){
        if (l==r) return;
        int mid=l+r>>1,ll=l-1,rr=mid;
        for (register int i=l;i<=r;i++){
            if (b[i].t<=mid) add(n-b[i].y+1);
            if (b[i].t>mid) ans[b[i].t][0]+=ask(n-b[i].y+1);
        }
        for (register int i=l;i<=r;i++)
        if (b[i].t<=mid) o[++ll]=b[i];else o[++rr]=b[i];
        for (register int i=l;i<=r;i++) b[i]=o[i];
        for (register int i=l;i<=r;i++) if (b[i].t<=mid) del(n-b[i].y+1);
        work0(l,mid);work0(mid+1,r);
    }
    inline void work1(int l,int r){
        if (l==r) return;
        int mid=l+r>>1,ll=l-1,rr=mid;
        for (register int i=l;i<=r;i++){
            if (y[i].t<=mid) add(y[i].y);
            if (y[i].t>mid) ans[y[i].t][1]+=ask(y[i].y);
        }
        for (register int i=l;i<=r;i++) if (y[i].t<=mid) del(y[i].y);
        for (register int i=l;i<=r;i++)
        if (y[i].t<=mid) o[++ll]=y[i];else o[++rr]=y[i];
        for (register int i=l;i<=r;i++) y[i]=o[i];
        work1(l,mid);work1(mid+1,r);
    }
    int main(){
        register int i,j=0;
        n=read();m=read();
        for (i=1;i<=n;i++) u[read()]=i;
        for (i=0;i<m;i++) ti[read()]=m-i;
        for (i=1;i<=n;i++){
            if (ti[i]==0) b[i].t=++j;else b[i].t=n-m+ti[i];
            b[i].x=u[i];b[i].y=i;
            y[i]=b[i];
        }
        sort(b+1,b+n+1,cmp);
        sort(y+1,y+n+1,tmp);
        work0(1,n);work1(1,n);
        for (int i=2;i<=n;i++) ans[i][0]+=ans[i-1][0],ans[i][1]+=ans[i-1][1];
        for (int i=n;i>j;i--) pr(ans[i][0]+ans[i][1]);
    }
    View Code
  • 相关阅读:
    调试
    webpack output的path publicPath
    CSS实现单行、多行文本溢出显示省略号
    docker安装mysql
    构建docker镜像
    Tensorflow博文列表
    ML理论知识博文列表
    Python博文列表
    Opencv博文收藏列表
    Centos文章列表
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5346434.html
Copyright © 2020-2023  润新知