zoukankan      html  css  js  c++  java
  • BZOJ 2141 排队

    题解:树套树

    不会带修主席树,留坑

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define lo now<<1
    #define ro now<<1|1
    using namespace std;
    const int maxn=20009;
    const int lgn=40;
    
    int n,TT;
    int ans=0;
    int h[maxn];
    
    int nn=0;
    int fa[maxn*lgn]={0},ch[maxn*lgn][2]={0};
    int ky[maxn*lgn]={0},siz[maxn*lgn]={0},cnt[maxn*lgn]={0};
    void pushup(int x){
        siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
    }
    int son(int x){
        if(ch[fa[x]][0]==x)return 0;
        else return 1;
    }
    void Rotate(int &root,int x){
        int y=fa[x];
        int z=fa[y];
        int b=son(x),c=son(y);
        int a=ch[x][b^1];
        if(z)ch[z][c]=x;
        else root=x;
        fa[x]=z;
        if(a)fa[a]=y;
        ch[y][b]=a;
        fa[y]=x;ch[x][b^1]=y;
        pushup(y);pushup(x);
    }
    void Splay(int &root,int x,int i){
        while(fa[x]!=i){
            int y=fa[x];
            int z=fa[y];
            if(z==i){
                Rotate(root,x);
            }else{
                if(son(x)==son(y)){
                    Rotate(root,y);Rotate(root,x);
                }else{
                    Rotate(root,x);Rotate(root,x);
                }
            }
        }
    }
    
    void Ins(int &root,int val){
        int x=root,y=0;
        while(x){
            y=x;
            if(ky[x]==val){
                ++cnt[x];++siz[x];
                Splay(root,x,0);return;
            }
            if(val>ky[x])x=ch[x][1];
            else x=ch[x][0];
        }
        x=++nn;
        fa[x]=y;siz[x]=cnt[x]=1;ky[x]=val;
        if(!y){
            root=x;
        }else{
            if(ky[x]>ky[y])ch[y][1]=x;
            else ch[y][0]=x;
        }
        Splay(root,x,0);
    }
    void Getval(int &root,int val){
        int x=root;
        while(x){
            if(ky[x]==val){
                Splay(root,x,0);
                return;
            }
            if(val>ky[x])x=ch[x][1];
            else x=ch[x][0];
        }
    }
    
    void Del(int &root,int val){
        Getval(root,val);
        int x=root;
        if(cnt[x]>1){
            --cnt[x];--siz[x];return;
        }
        if((!ch[x][0])&&(!ch[x][1])){
            root=0;
        }else if(!ch[x][0]){
            root=ch[x][1];
            fa[ch[x][1]]=0;
        }else if(!ch[x][1]){
            root=ch[x][0];
            fa[ch[x][0]]=0;
        }else{
            int p=ch[x][0];
            while(ch[p][1])p=ch[p][1];
            Splay(root,p,x);
            ch[p][1]=ch[x][1];
            fa[ch[x][1]]=p;
            fa[p]=0;root=p;pushup(p);
        }
    }
    
    int Getmin(int x,int val){
        int ret=0;
        while(x){
            if(ky[x]==val){
                return siz[ch[x][0]]+ret;
            }
            if(ky[x]<val){
                ret+=siz[ch[x][0]]+cnt[x];
                x=ch[x][1];
            }else{
                x=ch[x][0];
            }
        }
        return ret;
    }
    int Getmax(int x,int val){
        int ret=0;
        while(x){
            if(ky[x]==val){
                return siz[ch[x][1]]+ret;
            }
            if(ky[x]>val){
                ret+=siz[ch[x][1]]+cnt[x];
                x=ch[x][0];
            }else{
                x=ch[x][1];
            }
        }
        return ret;
    }
    
    struct SegmentTree{
        int l,r,root;
    }tree[maxn<<2];
    void BuildTree(int now,int l,int r){
        tree[now].l=l;tree[now].r=r;tree[now].root=0;
        for(int i=l;i<=r;++i){
            Ins(tree[now].root,h[i]);
        }
        if(l==r)return;
        int mid=(l+r)>>1;
        BuildTree(lo,l,mid);
        BuildTree(ro,mid+1,r);
    }
    void Updatapoint(int now,int pla,int x,int f){
        if(f==1)Ins(tree[now].root,x);
        else Del(tree[now].root,x);
        if(tree[now].l==tree[now].r)return;
        int mid=(tree[now].l+tree[now].r)>>1;
        if(pla<=mid)Updatapoint(lo,pla,x,f);
        else Updatapoint(ro,pla,x,f);
    }
    int Querysec(int now,int ll,int rr,int x,int f){
        if(ll>rr)return 0;
        if(tree[now].l>=ll&&tree[now].r<=rr){
            if(f==-1)return Getmin(tree[now].root,x);
            else return Getmax(tree[now].root,x);
        }
        int mid=(tree[now].l+tree[now].r)>>1;
        int ret=0;
        if(ll<=mid)ret+=Querysec(lo,ll,rr,x,f);
        if(rr>mid)ret+=Querysec(ro,ll,rr,x,f);
        return ret;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%d",&h[i]);
        BuildTree(1,1,n);
        for(int i=2;i<=n;++i){
            ans=ans+Querysec(1,1,i-1,h[i],1);
        }
        printf("%d
    ",ans);
        scanf("%d",&TT);
        while(TT--){
            int x,y;
            scanf("%d%d",&x,&y);
            if(h[x]==h[y]){
                printf("%d
    ",ans);
                continue;
            }
            if(x>y)swap(x,y);
            if(h[x]>h[y])--ans;
            else ++ans;
            ans+=Querysec(1,x+1,y-1,h[x],1);
            ans-=Querysec(1,x+1,y-1,h[x],-1);
            ans+=Querysec(1,x+1,y-1,h[y],-1);
            ans-=Querysec(1,x+1,y-1,h[y],1);
            Updatapoint(1,x,h[x],-1);
            Updatapoint(1,x,h[y],1);
            Updatapoint(1,y,h[y],-1);
            Updatapoint(1,y,h[x],1);
            swap(h[x],h[y]);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    python Database Poll for SQL SERVER
    SQLAlchemy表操作和增删改查
    flask动态url规则
    flask配置管理
    一个Flask运行分析
    Function Set in OPEN CASCADE
    Happy New Year 2016
    Apply Newton Method to Find Extrema in OPEN CASCADE
    OPEN CASCADE Multiple Variable Function
    OPEN CASCADE Gauss Least Square
  • 原文地址:https://www.cnblogs.com/zzyer/p/8647752.html
Copyright © 2011-2022 走看看