zoukankan      html  css  js  c++  java
  • 二逼平衡树 模板

    树套树板子题

    我写的是最普通的 外层线段树 套 里层权值$splay$

    第一个操作,求$K$在$[L,R]$的排名,在线段树中取出$[L,R]$区间的所有$splay$,每棵$splay$里都查询排名,相加即可,时间$O(log^{2}n)$

    第二个操作,求$[L,R]$中排名为$K$的数,二分一个值,到第一个操作里验证,时间$O(log^{3}n)$

    第三个操作,单点替换,在线段树里包含$x$的所有区间的$splay$里插入删除即可,时间$O(log^{2}n)$

    第四个操作,求$[L,R]$中$K$的前驱,在线段树中取出$[L,R]$区间的所有$splay$,每棵$splay$里都查询前驱,取最大的,时间$O(log^{2}n)$

    第五个操作,求$[L,R]$中$K$的后继,在线段树中取出$[L,R]$区间的所有$splay$,每棵$splay$里都查询后继,取最小的,时间$O(log^{2}n)$

    线段树套splay还挺暴力的..尤其是第二个操作

    人傻常数大,我的代码在洛谷吸氧才能过..

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #define N1 50500
      5 #define M1 1105000
      6 #define ll long long
      7 #define dd double
      8 #define inf 2147483647
      9 #define maxn 100000000
     10 using namespace std;
     11 
     12 int gint()
     13 {
     14     int ret=0,fh=1;char c=getchar();
     15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     17     return ret*fh;
     18 }
     19 int ret;
     20 struct Splay{
     21 int ch[M1][2],fa[M1],sz[M1],num[M1],val[M1],root[N1<<2],tot;
     22 //inline int idf(int x){return ch[fa[x]][0]==x?0;1;}
     23 inline void pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+num[x];}
     24 void rot(int x)
     25 {
     26     int y=fa[x],ff=fa[y],px=ch[fa[x]][0]==x?0:1;
     27     ch[ff][!(ch[fa[y]][0]==y)]=x; fa[x]=ff;
     28     fa[ch[x][px^1]]=y; ch[y][px]=ch[x][px^1]; 
     29     fa[y]=x; ch[x][px^1]=y; 
     30     pushup(y); pushup(x);
     31 }
     32 void splay(int x,int to,int id)
     33 {
     34     if(to==root[id]) root[id]=x;
     35     int y; to=fa[to];
     36     while(fa[x]!=to)
     37     {
     38         y=fa[x];
     39         if(fa[y]==to) rot(x);
     40         else if((ch[fa[x]][0]==x)^(ch[fa[y]][0]==y)) rot(x),rot(x);
     41         else rot(y),rot(x);
     42     }
     43 }
     44 int rank(int id,int w)
     45 {
     46     int x=root[id],p,ans=0;
     47     while(1)
     48     {
     49         if(val[x]==w){ ans+=sz[ch[x][0]]; break;}
     50         p=w<val[x]?0:1;
     51         if(p) ans+=sz[ch[x][0]]+num[x];
     52         if(!ch[x][p]) break;
     53         x=ch[x][p];
     54     }
     55     if(ret&1) splay(x,root[id],id);
     56     return ans;
     57 }
     58 int cre(int w){ tot++; val[tot]=w; sz[tot]=num[tot]=1; return tot;}
     59 void ins(int id,int w)
     60 {
     61     int x=root[id],p;
     62     while(x)
     63     {
     64         if(val[x]==w){ num[x]++; sz[x]++; break; }
     65         p=w<val[x]?0:1;
     66         if(!ch[x][p]){ ch[x][p]=cre(w); fa[ch[x][p]]=x; x=ch[x][p]; break;}
     67         else x=ch[x][p];
     68     }
     69     splay(x,root[id],id);
     70 }
     71 void init(int id){ root[id]=cre(-inf); sz[root[id]]=0; num[root[id]]=0; }
     72 int find(int id,int w)
     73 {
     74     int x=root[id],p;
     75     while(x)
     76     {
     77         if(val[x]==w) break; 
     78         p=w<val[x]?0:1;
     79         if(!ch[x][p]) return 0;
     80         x=ch[x][p];
     81     }
     82     splay(x,root[id],id);
     83     return x;
     84 }
     85 int lower(int id,int w)
     86 {
     87     int x=root[id],ans=-inf,p;
     88     while(1)
     89     {
     90         if(val[x]<w&&val[x]>ans) ans=val[x];
     91         p=w<=val[x]?0:1;
     92         if(!ch[x][p]) break;
     93         x=ch[x][p];
     94     }
     95     if(ret&1) splay(x,root[id],id);
     96     return ans;
     97 }
     98 int upper(int id,int w)
     99 {
    100     int x=root[id],ans=inf,p;
    101     while(1)
    102     {
    103         if(val[x]>w&&val[x]<ans) ans=val[x];
    104         p=w<val[x]?0:1;
    105         if(!ch[x][p]) break;
    106         x=ch[x][p];
    107     }
    108     if(ret&1) splay(x,root[id],id);
    109     return ans;
    110 }
    111 void des(int x){num[x]=sz[x]=ch[x][0]=ch[x][1]=fa[x]=val[x]=0;}
    112 void pop(int id,int w)
    113 {
    114     int x=find(id,w),y; if(!x) return; 
    115     if(num[x]>1){ num[x]--; return; }
    116     y=ch[x][0]; while(ch[y][1]) y=ch[y][1];
    117     fa[ch[x][1]]=y; ch[y][1]=ch[x][1];
    118     root[id]=ch[x][0]; des(x);
    119     splay(y,root[id],id);
    120 }
    121 }sp;
    122 int a[N1],n,m;
    123 struct SEG{
    124 void build(int l,int r,int rt)
    125 {
    126     int i,mid; sp.init(rt);
    127     for(i=l;i<=r;i++) sp.ins(rt,a[i]);
    128     if(l==r) return; mid=(l+r)>>1; 
    129     build(l,mid,rt<<1);
    130     build(mid+1,r,rt<<1|1);
    131 }
    132 int rank(int L,int R,int l,int r,int rt,int w)
    133 {
    134     if(L<=l&&r<=R){ return sp.rank(rt,w); }
    135     int mid=(l+r)>>1,ans=0;
    136     if(L<=mid) ans+=rank(L,R,l,mid,rt<<1,w);
    137     if(R>mid) ans+=rank(L,R,mid+1,r,rt<<1|1,w);
    138     return ans;
    139 }
    140 int srank(int L,int R,int K)
    141 {
    142     int l=0,r=maxn,mid,ans=0; K--;
    143     while(l<=r){
    144         mid=(l+r)>>1;
    145         if(rank(L,R,1,n,1,mid)<=K) ans=mid,l=mid+1;
    146         else r=mid-1;
    147     }return ans;
    148 }
    149 void update(int x,int l,int r,int rt,int w,int K)
    150 {
    151     sp.ins(rt,K); sp.pop(rt,w);
    152     if(l==r) return;
    153     int mid=(l+r)>>1;
    154     if(x<=mid) update(x,l,mid,rt<<1,w,K);
    155     else update(x,mid+1,r,rt<<1|1,w,K);
    156 }
    157 void raplace(int x,int K)
    158 {
    159     update(x,1,n,1,a[x],K);
    160     a[x]=K;
    161 }
    162 int lower(int L,int R,int l,int r,int rt,int w)
    163 {
    164     if(L<=l&&r<=R){ return sp.lower(rt,w); }
    165     int mid=(l+r)>>1,ans=-inf;
    166     if(L<=mid) ans=max(ans,lower(L,R,l,mid,rt<<1,w));
    167     if(R>mid) ans=max(ans,lower(L,R,mid+1,r,rt<<1|1,w));
    168     return ans;
    169 }
    170 int upper(int L,int R,int l,int r,int rt,int w)
    171 {
    172     if(L<=l&&r<=R){ return sp.upper(rt,w); }
    173     int mid=(l+r)>>1,ans=inf;
    174     if(L<=mid) ans=min(ans,upper(L,R,l,mid,rt<<1,w));
    175     if(R>mid) ans=min(ans,upper(L,R,mid+1,r,rt<<1|1,w));
    176     return ans;
    177 }
    178 }sg;
    179 
    180 int main()
    181 {
    182     scanf("%d%d",&n,&m);
    183     int i,j,op,l,r,K,ans;
    184     for(i=1;i<=n;i++) a[i]=gint();
    185     sg.build(1,n,1);
    186     for(i=1;i<=m;i++)
    187     {
    188         op=gint(); l=gint(); r=gint();
    189         switch(op)
    190         {
    191             case 1:{ K=gint(); ret=sg.rank(l,r,1,n,1,K); printf("%d
    ",ret+1); break; }
    192             case 2:{ K=gint(); ret=sg.srank(l,r,K); printf("%d
    ",ret); break; }
    193             case 3:{ sg.raplace(l,r); break; }
    194             case 4:{ K=gint(); ret=sg.lower(l,r,1,n,1,K); printf("%d
    ",ret); break; }
    195             case 5:{ K=gint(); ret=sg.upper(l,r,1,n,1,K); printf("%d
    ",ret); break; }
    196         }
    197     }
    198     return 0;
    199 }
  • 相关阅读:
    这家数据公司为什么能成为数百万企业的选择?
    这家数据公司为什么能成为数百万企业的选择?
    学会HTML就可以找工作了
    学会HTML就可以找工作了
    学会HTML就可以找工作了
    Linux学习笔记
    智能运维就是由 AI 代替运维人员?
    技术团队管理(1)
    maven 总分项目打包指令
    Python 2 和 3 的区别及兼容技巧
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10221783.html
Copyright © 2011-2022 走看看