zoukankan      html  css  js  c++  java
  • [CQOI2011]动态逆序对

    Description

    给定一个排列,每次删除一个元素,输出当前逆序对个数。

    Solution

    原序列的逆序对个数很好求。现在考虑删除一个数对答案的贡献。对每个元素,我们记一个它的大小 (v),它在序列中的位置下标 (pos),它被删除的时间 (t),对于没有被删除的元素,其删除时间设为 (m+1),即删除的元素个数加一。那么删除一个下标为 (i) 数会减少的逆序对个数就可以按下标大小分成两半来求。

    [egin{cases} i<j \ v_i>v_j \ t_i<t_j end{cases} quad egin{cases} i>j \ v_i<v_j \ t_i<t_j end{cases} ]

    容易发现都是三维偏序,直接 CDQ 分治即可。

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define N 100007
    #define ll long long
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    struct Node{
        int pos,t,val;
        ll ans;
    }a[N];
    
    ll c[N];
    int n,m,D[N];
    
    inline int lowbit(int x){return (-x)&x;}
    inline void add(int x,ll v){while(x<=n)c[x]+=v,x+=lowbit(x);}
    inline ll query(int x){ll ret=0;while(x)ret+=c[x],x-=lowbit(x);return ret;}
    
    inline bool Cmp1(const Node &X,const Node &Y){return X.t!=Y.t? X.t>Y.t:X.pos>Y.pos;}
    inline bool Cmp2(const Node &X,const Node &Y){return X.pos>Y.pos;}
    inline bool Cmp3(const Node &X,const Node &Y){return X.val>Y.val;}
    
    void CDQ(int lf,int rf){
        if(lf==rf) return ;
        int mid=(lf+rf)>>1;
        CDQ(lf,mid),CDQ(mid+1,rf);
        sort(a+lf,a+mid+1,Cmp2),sort(a+mid+1,a+rf+1,Cmp2);
        int i=mid+1,j=lf-1;
        for(;i<=rf;i++){
            while(j<mid&&a[j+1].pos>a[i].pos)
                ++j,add(a[j].val,1);
            a[i].ans+=query(a[i].val-1);
        }
        for(i=lf;i<=j;i++) add(a[i].val,-1);
        sort(a+lf,a+mid+1,Cmp3),sort(a+mid+1,a+rf+1,Cmp3);
        i=mid+1,j=lf-1;
        for(;i<=rf;i++){
            while(j<mid&&a[j+1].val>a[i].val)
                ++j,add(a[j].pos,1);
            a[i].ans+=query(a[i].pos-1);
        }
        for(i=lf;i<=j;i++) add(a[i].pos,-1);
    }
    
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++) a[i].val=read(),D[a[i].val]=a[i].pos=i;
        for(int i=1;i<=m;i++) a[D[read()]].t=i;
        for(int i=1;i<=n;i++) if(!a[i].t) a[i].t=m+1;
        ll ans=0;
        for(int i=1;i<=n;i++){
            ans+=query(n-a[i].val+1);
            add(n-a[i].val+1,1);
        }
        for(int i=1;i<=n;i++) c[i]=0;
        sort(a+1,a+1+n,Cmp1),CDQ(1,n);
        sort(a+1,a+1+n,Cmp1);
        for(int i=n;i>n-m;i--){
            printf("%lld
    ",ans);
            ans-=a[i].ans;
        }
    }
    
  • 相关阅读:
    未来经济形势未来会怎么样呢疑问?
    今天开车开锅啦!没有经验惹得祸,修了一天的汽车!(开车经验教训学习)
    《飓风营救》(Taken)(父女情深电影推荐)
    The Pursuit of Happyness 当幸福来敲门(励志电影推荐)
    老婆入院待产观察
    闵行区电动自行车上牌地址
    (转载)中国99%白领要破产 买房干嘛???
    日食图片(转载)
    简单的配置iis让主机支持wap
    大数据量的分页存储过程代码
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/14470548.html
Copyright © 2011-2022 走看看