zoukankan      html  css  js  c++  java
  • 树套树

    在一个树形数据结构上的每个节点都是一个树形数据结构

    支持操作

    ① 查询(k)在区间内的排名(通过线段树来合并区间来统计答案)

    ② 查询区间内排名为(k)的值(通过二分实现,用查询排名来(check)

    ③ 修改某一位值上的数值(线段树单点修改,同时更新平衡树)

    ④ 查询(k)在区间内的前驱(通过线段树来合并区间来统计答案)

    ⑤ 查询(k)在区间内的后继(通过线段树来合并区间来统计答案)

    线段树套(FHQ Treap)

    (code:)

    struct FHQ_Treap
    {
        int root,x,y,z;
        int add(int x)
        {
            val[++tot]=x;
            siz[tot]=1;
            key[tot]=rand();
            return tot;
        }
        void pushup(int x)
        {
            siz[x]=siz[ls[x]]+siz[rs[x]]+1;
        }
        void merge(int &p,int x,int y)
        {
            if(!x||!y)
            {   
                p=x+y;
                return;
            }
            if(key[x]<key[y]) p=x,merge(rs[p],rs[p],y);
            else p=y,merge(ls[p],x,ls[p]);
            pushup(p);
        }
        void split(int p,int k,int &x,int &y)
        {
            if(!p)
            {
                x=y=0;
                return;
            }
            if(val[p]<=k) x=p,split(rs[p],k,rs[p],y);
            else y=p,split(ls[p],k,x,ls[p]);
            pushup(p);
        }
        void insert(int v)
        {
            split(root,v,x,y);
            merge(x,x,add(v));
            merge(root,x,y);
        }
        void del(int v)
        {
            split(root,v,x,y);
            split(x,v-1,x,z);
            merge(z,ls[z],rs[z]);
            merge(x,x,z);
            merge(root,x,y);
        }
        void build(int l,int r)
        {
            for(int i=l;i<=r;++i) insert(a[i]);
        }
        int kth(int v)
        {
            split(root,v-1,x,y);
            int ans=siz[x]+1;
            merge(root,x,y);
            return ans;
        }
        int get(int p,int k)
        {
            if(k==siz[ls[p]]+1) return val[p];
            if(k<=siz[ls[p]]) return get(ls[p],k);
            else return get(rs[p],k-siz[ls[p]]-1);
        }
        int pre(int v)
        {
            split(root,v-1,x,y);
            int ans;
            if(siz[x]) ans=get(x,siz[x]);
            else ans=-inf;
            merge(root,x,y);
            return ans;
        }
        int nxt(int v)
        {
            split(root,v,x,y);
            int ans;
            if(siz[y]) ans=get(y,1);
            else ans=inf;
            merge(root,x,y);
            return ans;
        }
    }treap[maxn];
    struct Segment_Tree
    {
        void build(int l,int r,int &cur)
        {
            cur=++tree_cnt;
            treap[cur].build(l,r);
            if(l==r) return;
            int mid=(l+r)>>1;
            build(l,mid,lc[cur]),build(mid+1,r,rc[cur]);
        }
        int q_rnk(int L,int R,int l,int r,int k,int cur)
        {
            if(L<=l&&R>=r)  return treap[cur].kth(k)-1;
            int mid=(l+r)>>1,ans=0;
            if(L<=mid) ans+=q_rnk(L,R,l,mid,k,lc[cur]);
            if(R>mid) ans+=q_rnk(L,R,mid+1,r,k,rc[cur]);
            return ans;
        }
        int q_val(int L,int R,int rnk)
        {
            int l=0,r=1e8,ans;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(q_rnk(L,R,1,n,mid,root)+1<=rnk) ans=mid,l=mid+1;
                else r=mid-1;
            }
            return ans;
        }
        void modify(int l,int r,int pos,int k,int cur)
        {
            treap[cur].del(a[pos]),treap[cur].insert(k);
            if(l==r) return;
            int mid=(l+r)>>1;
            if(pos<=mid) modify(l,mid,pos,k,lc[cur]);
            if(pos>mid) modify(mid+1,r,pos,k,rc[cur]);
        }
        int lower(int L,int R,int l,int r,int k,int cur)
        {
            if(L>r||R<l) return -inf;
            if(L<=l&&R>=r) return treap[cur].pre(k);
            int mid=(l+r)>>1;
            return max(lower(L,R,l,mid,k,lc[cur]),lower(L,R,mid+1,r,k,rc[cur]));
        }
        int upper(int L,int R,int l,int r,int k,int cur)
        {
            if(L>r||R<l) return inf;
            if(L<=l&&R>=r) return treap[cur].nxt(k);
            int mid=(l+r)>>1;
            return min(upper(L,R,l,mid,k,lc[cur]),upper(L,R,mid+1,r,k,rc[cur]));
        }
    }tree;
    
  • 相关阅读:
    hive查询语句合并问题
    hive isnull或ifnull的替代方法if()方法
    hive科学计数法引发的问题
    科学计数法转字符串
    shell命令执行结果$?
    shell脚本中变量接受hive语句的返回值问题
    shell简单命令
    js切换图片
    js点击图片切换
    操作节点
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229618.html
Copyright © 2011-2022 走看看