zoukankan      html  css  js  c++  java
  • bzoj3295: [Cqoi2011]动态逆序对

    3295: [Cqoi2011]动态逆序对

    Description

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

    Input

    输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数。

    以下n行每行包含一个1到n之间的正整数,即初始排列。

    以下m行每行一个正整数,依次为每次删除的元素。

    Output

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

    数据范围

    $N \leqslant 100000 , M \leqslant50000 $

    这道题将插入时间转化为一维,就是个三维偏序,直接cdq即可。

    注意输入的是元素大小,而不是元素个数。

    #include<bits/stdc++.h>
    using namespace std;
    #define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
    #define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
    typedef long long ll;
    inline int read(){
        int x;
        char c;
        int f=1;
        while((c=getchar())!='-' && (c<'0' || c>'9'));
        if(c=='-') c=getchar(),f=-1;
        x=c^'0';
        while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
        return x*f;
    }
    inline ll readll(){
        ll x;
        char c;
        ll f=1;
        while((c=getchar())!='-' && (c<'0' || c>'9'));
        if(c=='-') c=getchar(),f=-1;
        x=c^'0';
        while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
        return x*f;
    }
    inline bool chkmax(int &x,int y){return (y>x)?(x=y,1):0;}
    inline bool chkmin(int &x,int y){return (y<x)?(x=y,1):0;}
    const int maxn=1e5+10;
    struct point{
        int x,y,z,sum;
    }a[maxn];
    bool cmpx(const point A,const point B){
        if(A.x!=B.x) return A.x<B.x;
        if(A.y!=B.y) return A.y<B.y;
        return A.z<B.z;
    }
    bool cmpy(const point A,const point B){
        if(A.y!=B.y) return A.y<B.y;
        return A.z<B.z;
    }
    int n;
    ll ans[maxn];
    struct szsz{
        int c[maxn];
        int lowbit(int x){
            return x&(-x);
        }
        int sum(int x){
            int res=0;
            while(x){
                res+=c[x];
                x-=lowbit(x);
            }
            return res;
        }
        void add(int x,int y){
            while(x<=n){
                c[x]+=y;
                x+=lowbit(x);
            }
        }
    }bit;
    void cdq(int L,int R){
        if(L>=R) return;
        int Mid=(L+R)>>1;
        cdq(L,Mid),cdq(Mid+1,R);
        sort(a+L,a+Mid+1,cmpy),sort(a+Mid+1,a+R+1,cmpy);
        int j=L;
        for(int i=Mid+1;i<=R;++i){
            while(j<=Mid && a[j].y<=a[i].y) bit.add(a[j].z,1),++j;
            a[i].sum+=bit.sum(n)-bit.sum(a[i].z);
        }
        REP(i,L,j-1) bit.add(a[i].z,-1);
        j=Mid;
        for(int i=R;i>Mid;--i){
            while(j>=L && a[j].y>=a[i].y) bit.add(a[j].z,1),--j;
            a[i].sum+=bit.sum(a[i].z);
        }
        DREP(i,Mid,j+1) bit.add(a[i].z,-1);
    }
    int mp[maxn];
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("cdq.in","r",stdin);
        freopen("cdq.out","w",stdout);
    #endif
        n=read();int m=read();
        REP(i,1,n) a[i].x=0,a[i].y=i,a[i].z=read(),mp[a[i].z]=i;
        int num=n;
        REP(i,1,m){
            int x=read();x=mp[x];
            a[x].x=num--;
        }
        REP(i,1,m) if(a[i].x==0) a[i].x=num--;
        sort(a+1,a+n+1,cmpx);
        cdq(1,n);
        REP(i,1,n) ans[a[i].x]+=a[i].sum;
        REP(i,1,n) ans[i]+=ans[i-1];
        DREP(i,n,n-m+1) printf("%lld\n",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    SQL Server(00):约束Constraint
    SQL Server(00):T-SQL批处理
    SQL Server(00):事务
    SQL Server(00):锁
    SQL Server(00):表变量和临时表
    SQL Server(00):T-SQL游标
    SQL Server(00):用户自定义函数(UDF)
    SQL Server(00):存储过程Stored Procedure
    C#(99):微软报表A4纸大小规则
    C#(99):C#互操作
  • 原文地址:https://www.cnblogs.com/zhou888/p/8511904.html
Copyright © 2011-2022 走看看