• bzoj3295 [Cqoi2011]动态逆序对


    bzoj3295 [Cqoi2011]动态逆序对

    一道好题啊= =据说CDQ(不会),分块(Orz)都能过。
    树状数组套主席树题= =
    首先树状数组求出逆序对数。
    然后每次需要删除一个数,也要删除与它相关的逆序对。
    与一个数(a=s_i)能组成逆序对的数(b=s_j),要满足(i>j,a<b)(i<j,a>b)
    然后对应着线段树里的查询。
    转化一下,(i<j,a>b)的数量可以转化成所有(a>b)的数量减去(i>j,a>b)的数量
    (i>j,a<b)(i>j,a>b)的数量
    对应着树状数组的查询。
    所有(a>b)的数量在开始那个树状数组里搞搞。
    其余都是套板子。。


    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    #define lowbit(i) ((i)&-(i))
    typedef long long ll;
    il char gc(){
        const int B=233333;static char b[233334],*p=b+B;
        if(p==b+B)b[fread(b,1,B,stdin)]=0,p=b;
        return *p?*p++:0;
    }
    il ll gi(){
        rg ll x=0;rg bool flg=0;rg char ch=gc();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=gc();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=gc();
        return flg?-x:x;
    }
    const int maxn=1e5+1;
    int n,m,st[maxn],__pos[maxn];
    namespace init_inverse{
        int TREE[maxn];
        il vd add(int pos){while(pos<=n)++TREE[pos],pos+=lowbit(pos);}
        il vd _add(int pos){while(pos<=n)--TREE[pos],pos+=lowbit(pos);}
        il int sum(int pos){static int ret;ret=0;while(pos)ret+=TREE[pos],pos-=lowbit(pos);return ret;}
        il ll solve(){
            ll ret=0;
            drep(i,n,1)add(st[i]),ret+=sum(st[i]-1);
            return ret;
        }
        il ll del(int x){static ll ret;ret=sum(x-1);_add(x);return ret;}
    }
    namespace DS{    //DS == Data Structure
        int ls[maxn*100],rs[maxn*100],tot[maxn*100],rt[maxn],_cnt=0;
    #define mid ((l+r)>>1)
        il vd Updata(int&x,const int&l,const int&r,const int&pos,const int&num){
            if(!x)x=++_cnt;tot[x]+=num;
            if(l==r)return;
            if(pos<=mid)Updata(ls[x],l,mid,pos,num);
            else Updata(rs[x],mid+1,r,pos,num);
        }
        il int Query(const int&x,const int&l,const int&r,const int&_l,const int&_r){
            if(_l>_r)return 0;
            if(_l<=l&&r<=_r)return tot[x];
            if(_l<=mid)
                if(_r>mid)return Query(ls[x],l,mid,_l,_r)+Query(rs[x],mid+1,r,_l,_r);
                else return Query(ls[x],l,mid,_l,_r);
            else return Query(rs[x],mid+1,r,_l,_r);
        }
    #undef mid
        il vd init(){rep(i,1,n)for(int j=i;j<=n;j+=lowbit(j))Updata(rt[j],1,n,st[i],1);}
        il ll del(int x){
            ll ret=init_inverse::del(x);
            for(int j=__pos[x]-1;j;j-=lowbit(j))ret+=Query(rt[j],1,n,x+1,n)-Query(rt[j],1,n,1,x-1);
            for(int j=__pos[x];j<=n;j+=lowbit(j))Updata(rt[j],1,n,x,-1);
            return ret;
        }
    }
    int main(){
        n=gi(),m=gi();
        rep(i,1,n)st[i]=gi(),__pos[st[i]]=i;
        ll ans=init_inverse::solve();
        DS::init();
        while(m--){
            printf("%lld
    ",ans);
            ans-=DS::del(gi());
        }
        return 0;
    }
    
  • 相关阅读:
    遍历mac系统访达文件时候要注意了
    python r+ 是追加写
    Linux如何给一个python被挂起进程传递命令?
    nohup后台挂起
    树莓派建站全过程
    wechat robot
    廖雪峰笔记(转网络专题)
    【转】 前端笔记之JavaScript(十一)event&amp;BOM&amp;鼠标/盒子位置&amp;拖拽/滚轮
    【转】 前端笔记之JavaScript(十)深入JavaScript节点&amp;DOM&amp;事件
    【转】 前端笔记之JavaScript(九)定时器&amp;JSON&amp;同步异步/回调函数&amp;函数节流&amp;call/apply
  • 原文地址:https://www.cnblogs.com/xzz_233/p/bzoj3295.html
Copyright © 2020-2023  润新知