zoukankan      html  css  js  c++  java
  • 树套树-线段树套平衡树

    树套树留坑

    线段树套平衡树:

    二逼平衡树

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<bitset>
    #pragma GCC optimize(2)
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int N=6000000,inf=2147483647;
    int n,m,maxn,a[N+10];
    int tot,rt[N+10],sz[N+10],rec[N+10],v[N+10],fa[N+10],ch[N+10][2];
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    //----------------------Splay--------------------------
    inline int ident(int x){return ch[fa[x]][0]==x?0:1;}
    inline void splay_clear(int x){fa[x]=ch[x][0]=ch[x][1]=sz[x]=rec[x]=v[x]=0;}
    inline void splay_pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+rec[x];}
    inline void rotate(int x)
    {
        int Y=fa[x],R=fa[Y],Yson=ident(x),Rson=ident(Y);
        if(R)ch[R][Rson]=x;
        if(ch[x][Yson^1]) fa[ch[x][Yson^1]]=Y;
        ch[Y][Yson]=ch[x][Yson^1];
        ch[x][Yson^1]=Y;
        fa[Y]=x;
        fa[x]=R;
        splay_pushup(Y),splay_pushup(x);
    }
    inline void splay(int &rt,int x,int to)
    {
        to=fa[to];
        while(fa[x]!=to)
        {
            int y=fa[x];
            if(fa[y]==to) rotate(x);
            else if(ident(x)==ident(y)) rotate(y),rotate(x);
            else rotate(x),rotate(x);
        }
        if(!to) rt=x;
    }
    inline void splay_insert(int &rt,int d)
    {
        if(!rt)
        {
            rt=++tot;
            v[rt]=d;
            sz[rt]=rec[rt]=1;
            fa[rt]=ch[rt][0]=ch[rt][1]=0;
            return;
        }
        int x=rt;
        while(1)
        {
            sz[x]++;
            if(v[x]==d){rec[x]++;splay(rt,x,rt);return;}
            int nxt=d<v[x]?0:1;
            if(!ch[x][nxt])
            {
                ch[x][nxt]=++tot;
                v[tot]=d;
                sz[tot]=rec[tot]=1;
                fa[tot]=x;
                ch[tot][0]=ch[tot][1]=0;
                splay(rt,tot,rt);
                return;
            }
            x=ch[x][nxt];
        }
    }
    inline int splay_rk(int &rt,int d)
    {
        int x=rt,ans=0;
        while(1)
        {
            if(!x){return ans;}
            if(v[x]==d){ans+=sz[ch[x][0]];splay(rt,x,rt);return ans;}
            int nxt=d<v[x]?0:1;
            if(nxt==1) ans+=sz[ch[x][0]]+rec[x];
            x=ch[x][nxt];
        }
    }
    inline int splay_find(int &rt,int d)
    {
        int x=rt;
        while(1)
        {
            if(!x) return 0;
            if(v[x]==d){splay(rt,x,rt);return x;}
            int nxt=d<v[x]?0:1;
            x=ch[x][nxt];
        }
    }
    inline void splay_del(int &rt,int d)
    {
        int x=splay_find(rt,d);
        if(!x) return;
        if(rec[x]>=2){rec[x]--,sz[x]--;return;}
        if(!ch[x][0]&&!ch[x][1]){rt=0;return;}
        if(!ch[x][0]){rt=ch[x][1];fa[rt]=0;return;}
        if(!ch[x][1]){rt=ch[x][0];fa[rt]=0;return;}
        int left=ch[x][0];
        while(ch[left][1]) left=ch[left][1];
        splay(rt,left,ch[x][0]);
        fa[ch[x][1]]=left;
        ch[left][1]=ch[x][1];
        fa[left]=0;
        rt=left;
        splay_pushup(left);
    }
    inline int splay_lower(int &rt,int d)
    {
        int x=rt,ans=-inf;
        while(x)
        {
            if(v[x]<d) ans=max(ans,v[x]);
            int nxt=d<=v[x]?0:1;
            x=ch[x][nxt];
        }
        return ans;
    }
    inline int splay_upper(int &rt,int d)
    {
        int x=rt,ans=inf;
        while(x)
        {
            if(v[x]>d) ans=min(ans,v[x]);
            int nxt=d<v[x]?0:1;
            x=ch[x][nxt];
        }
        return ans;
    }
    //----------------------Seg_Tree--------------------------
    void seg_insert(int k,int l,int r,int x,int d)
    {
        splay_insert(rt[k],d);
        if(l==r) return;
        int mid=(l+r)>>1;
        if(x<=mid) seg_insert(k<<1,l,mid,x,d);
        else seg_insert(k<<1|1,mid+1,r,x,d);
    }
    int seg_rk(int k,int l,int r,int ql,int qr,int d)
    {
    
        if(ql<=l&&r<=qr){return splay_rk(rt[k],d);}
        int ans=0,mid=(l+r)>>1;
        if(ql<=mid) ans+=seg_rk(k<<1,l,mid,ql,qr,d);
        if(qr>=mid+1) ans+=seg_rk(k<<1|1,mid+1,r,ql,qr,d);
        return ans;
    }
    void seg_change(int k,int l,int r,int x,int d)
    {
        splay_del(rt[k],a[x]),splay_insert(rt[k],d);
        if(l==r){a[x]=d;return;}
        int mid=(l+r)>>1;
        if(x<=mid) seg_change(k<<1,l,mid,x,d);
        else seg_change(k<<1|1,mid+1,r,x,d);
    }
    int seg_lower(int k,int l,int r,int ql,int qr,int d)
    {
        if(ql<=l&&r<=qr) return splay_lower(rt[k],d);
        int ans=-inf,mid=(l+r)>>1;
        if(ql<=mid) ans=max(ans,seg_lower(k<<1,l,mid,ql,qr,d));
        if(qr>=mid+1) ans=max(ans,seg_lower(k<<1|1,mid+1,r,ql,qr,d));
        return ans;
    }
    int seg_upper(int k,int l,int r,int ql,int qr,int d)
    {
        if(ql<=l&&r<=qr) return splay_upper(rt[k],d);
        int ans=inf,mid=(l+r)>>1;
        if(ql<=mid) ans=min(ans,seg_upper(k<<1,l,mid,ql,qr,d));
        if(qr>=mid+1) ans=min(ans,seg_upper(k<<1|1,mid+1,r,ql,qr,d));
        return ans;
    }
    inline int seg_kth(int ql,int qr,int k)
    {
        int l=0,r=maxn+1,ans;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(seg_rk(1,1,n,ql,qr,mid)+1<=k) ans=mid,l=mid+1;
            else r=mid-1;
        }
        return ans;
    }
    int main()
    {
        n=read(),m=read();
        rep(i,1,n) a[i]=read(),seg_insert(1,1,n,i,a[i]),maxn=max(maxn,a[i]);
        rep(i,1,m)
        {
            int opt=read(),x=read(),y=read(),k;
            if(opt==1) k=read(),printf("%d
    ",seg_rk(1,1,n,x,y,k)+1);
            if(opt==2) k=read(),printf("%d
    ",seg_kth(x,y,k));
            if(opt==3) maxn=max(maxn,y),seg_change(1,1,n,x,y);
            if(opt==4) k=read(),printf("%d
    ",seg_lower(1,1,n,x,y,k));
            if(opt==5) k=read(),printf("%d
    ",seg_upper(1,1,n,x,y,k));
        }
        return 0;
    }
    
  • 相关阅读:
    路由懒加载
    Generator函数
    属性特性get/set
    审核功能
    纯js实现最简单的文件上传(后台使用MultipartFile)
    shiro+redis多次调用doReadSession方法的解决方案
    nginx-windows版
    Spring—Quartz定时调度CronTrigger时间配置格式说明与实例
    java中获取文件目录
    mysql 在update中实现子查询的方式
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/11403309.html
Copyright © 2011-2022 走看看