1. 程式人生 > >二逼平衡樹 模板

二逼平衡樹 模板

樹套樹板子題

我寫的是最普通的 外層線段樹 套 裡層權值$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\n",ret+1); break; } 192 case 2:{ K=gint(); ret=sg.srank(l,r,K); printf("%d\n",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\n",ret); break; } 195 case 5:{ K=gint(); ret=sg.upper(l,r,1,n,1,K); printf("%d\n",ret); break; } 196 } 197 } 198 return 0; 199 }