zoukankan      html  css  js  c++  java
  • BZOJ3196:二逼平衡树

    浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html

    浅谈(Splay)https://www.cnblogs.com/AKMer/p/9979592.html

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3196

    树套树模板题,外层用一个位置线段树,内层用一个平衡树即可解决。

    查第(k)大是谁需要在外面套一个二分。这题比较卡,反正我是勉勉强强跑过去的……

    时间复杂度:(O(nlog^3n))

    空间复杂度:(O(nlogn))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=5e4+5,inf=2147483647;
    
    int a[maxn];
    int n,m,mn=1e9,mx=-1e9;
    
    int read() {
        int x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    struct Splay {
        int tot;
        int son[maxn*25][2],fa[maxn*25];
        int siz[maxn*25],cnt[maxn*25],val[maxn*25];
    
        int newnode(int v) {
            val[++tot]=v;
            siz[tot]=cnt[tot]=1;
            return tot;
        }
    
        int find(int rt,int v) {
            int u=rt;
            while(val[u]!=v) {
                if(val[u]>v) {if(son[u][0])u=son[u][0];else break;}
                if(val[u]<v) {if(son[u][1])u=son[u][1];else break;}
            }
            return u;
        }
    
        int t(int u) {
            return son[fa[u]][1]==u;
        }
    
        void updata(int u) {
            siz[u]=siz[son[u][0]]+cnt[u]+siz[son[u][1]];
        }
    
        void rotate(int u) {
            int ret=t(u),f=fa[u],s=son[u][ret^1];
            son[f][ret]=s;if(s)fa[s]=f;son[u][ret^1]=f;
            fa[u]=fa[f];if(fa[f])son[fa[f]][t(f)]=u;
            fa[f]=u;updata(f);updata(u);
        }
    
        void splay(int &rt,int u) {
            while(fa[u]) {
                if(fa[fa[u]]) {
                    if(t(fa[u])!=t(u))rotate(u);
                    else rotate(fa[u]);
                }
                rotate(u);
            }
            rt=u;
        }
        
        void ins(int &rt,int v) {
            if(!rt) {rt=newnode(v);return;}
            int u=find(rt,v);
            if(val[u]==v) {siz[u]++,cnt[u]++,splay(rt,u);return;}
            fa[newnode(v)]=u;son[u][v>val[u]]=tot;splay(rt,tot);
        }
    
        int get_rk(int &rt,int v) {
            int u=find(rt,v);splay(rt,u);
            if(val[u]>=v)return siz[son[u][0]];
            return siz[son[u][0]]+cnt[u];
        }
    
        void del(int &rt,int v) {
            int u=find(rt,v);splay(rt,u);
            if(cnt[u]>1) {cnt[u]--,siz[u]--;return;}
            if(!son[u][0]) {rt=son[u][1],fa[rt]=0;return;}
            if(!son[u][1]) {rt=son[u][0],fa[rt]=0;return;}
            int node=son[u][0];while(son[node][1])node=son[node][1];
            fa[son[u][0]]=0;splay(rt,node);
            son[node][1]=son[u][1];fa[son[u][1]]=node;
            updata(node);
        }
    
        int get_pre(int &rt,int v) {
            int u=find(rt,v);splay(rt,u);
            if(val[u]<v)return val[u];
            int node=son[u][0];
            while(son[node][1])node=son[node][1];
            if(node)return val[node];
            return -inf;
        }
    
        int get_suc(int &rt,int v) {
            int u=find(rt,v);splay(rt,u);
            if(val[u]>v)return val[u];
            int node=son[u][1];
            while(son[node][0])node=son[node][0];
            if(node)return val[node];
            return inf;
        }
    }S;
    
    struct segment_tree {
        int rt[maxn<<2];
    
        void build(int p,int l,int r) {
            for(int i=l;i<=r;i++)
                S.ins(rt[p],a[i]);
            if(l==r)return;
            int mid=(l+r)>>1;
            build(p<<1,l,mid);
            build(p<<1|1,mid+1,r);
        }
    
        int query_rk(int p,int l,int r,int L,int R,int v) {
            if(L<=l&&r<=R)return S.get_rk(rt[p],v);
            int mid=(l+r)>>1,res=0;
            if(L<=mid)res=query_rk(p<<1,l,mid,L,R,v);
            if(R>mid)res+=query_rk(p<<1|1,mid+1,r,L,R,v);
            return res;
        }
    
        void change(int p,int l,int r,int pos,int v_before,int v_after) {
            S.del(rt[p],v_before);S.ins(rt[p],v_after);
            if(l==r)return;	int mid=(l+r)>>1;
            if(pos<=mid)change(p<<1,l,mid,pos,v_before,v_after);
            else change(p<<1|1,mid+1,r,pos,v_before,v_after);
        }
    
        int query_pre(int p,int l,int r,int L,int R,int v) {
            if(L<=l&&r<=R)return S.get_pre(rt[p],v);
            int mid=(l+r)>>1,res=-inf;
            if(L<=mid)res=max(res,query_pre(p<<1,l,mid,L,R,v));
            if(R>mid)res=max(res,query_pre(p<<1|1,mid+1,r,L,R,v));
            return res;
        }
    
        int query_suc(int p,int l,int r,int L,int R,int v) {
            if(L<=l&&r<=R)return S.get_suc(rt[p],v);
            int mid=(l+r)>>1,res=inf;
            if(L<=mid)res=min(res,query_suc(p<<1,l,mid,L,R,v));
            if(R>mid)res=min(res,query_suc(p<<1|1,mid+1,r,L,R,v));
            return res;
        }
    }T;
    
    int main() {
        n=read(),m=read();
        for(int i=1;i<=n;i++)
            a[i]=read(),mn=min(mn,a[i]),mx=max(mx,a[i]);
        T.build(1,1,n);
        for(int i=1;i<=m;i++) {
            int opt=read(),l,r,pos,k;
            if(opt==3)pos=read(),k=read();
            else l=read(),r=read(),k=read();
            if(opt==1)printf("%d
    ",T.query_rk(1,1,n,l,r,k)+1);
            if(opt==2) {
                int L=mn,R=mx;
                while(L<R) {
                    int mid=(L+R+1)>>1;
                    int rk=T.query_rk(1,1,n,l,r,mid)+1;
                    if(rk>k)R=mid-1;
                    else L=mid;
                }
                printf("%d
    ",L);
            }
            if(opt==3)T.change(1,1,n,pos,a[pos],k),a[pos]=k,mn=min(mn,k),mx=max(mx,k);
            if(opt==4)printf("%d
    ",T.query_pre(1,1,n,l,r,k));
            if(opt==5)printf("%d
    ",T.query_suc(1,1,n,l,r,k));
        }
        return 0;
    }
    
  • 相关阅读:
    Android游戏开发:游戏框架的搭建(4)
    Android游戏开发:游戏框架的搭建(2)
    android之HttpURLConnection
    Android游戏开发:游戏框架的搭建(3)
    Socket连接与HTTP连接
    Java初级优化
    Android文件操作总结
    android GC内存泄露问题
    Java高级优化技术
    JAVA中三种URL连接方法
  • 原文地址:https://www.cnblogs.com/AKMer/p/10167273.html
Copyright © 2011-2022 走看看