【模板】二逼平衡树

时间:2022-11-26 04:29:16

线段树套splay:

  这是个永远不想打第二遍的模板

  1 #include<bits/stdc++.h>
2 #define R register
3 using namespace std;
4 const int N=50010,NN=2000010,oo=2147483647;
5 int n,m,a[N];
6 int fa[NN],ch[NN][2],v[NN],siz[NN],cnt[NN],tot;
7 int ls[N<<2],rs[N<<2],root[N<<2];
8 inline int read(){
9 int x=0,w=1;char c=0;
10 while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
11 while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
12 return x*w;
13 }
14 struct Splay{
15 inline bool getside(int k){return ch[fa[k]][1]==k;}
16 void updata(int k){
17 siz[k]=cnt[k];
18 if(ch[k][0]) siz[k]+=siz[ch[k][0]];
19 if(ch[k][1]) siz[k]+=siz[ch[k][1]];
20 }
21 void rotate(int k){
22 int old=fa[k],oldf=fa[old],sidek=getside(k),sideold=getside(old);
23 ch[old][sidek]=ch[k][sidek^1];
24 if(ch[k][sidek^1]) fa[ch[k][sidek^1]]=old;
25 fa[old]=k,ch[k][sidek^1]=old,fa[k]=oldf;
26 if(oldf) ch[oldf][sideold]=k;
27 updata(old);updata(k);
28 return;
29 }
30 void splay(int& r,int k,int aim){
31 for(int i=fa[k];i!=aim;i=fa[k])
32 rotate(getside(k)==getside(i)&&fa[i]!=aim?i:k);
33 if(!aim) r=k;
34 return;
35 }
36 void insert(int& r,int x){
37 if(!r){
38 r=++tot;
39 fa[tot]=0,ch[tot][0]=ch[tot][1]=0,siz[tot]=cnt[tot]=1,v[tot]=x;
40 return;
41 }
42 R int now=r,pre=0;
43 int side;
44 while(now){
45 pre=now;
46 if(v[now]==x){
47 cnt[now]++;
48 splay(r,now,0);
49 return;
50 }else if(v[now]>x) now=ch[now][0];
51 else now=ch[now][1];
52 }
53 side=v[pre]<x;
54 ch[pre][side]=++tot;
55 fa[tot]=pre,v[tot]=x,cnt[tot]=1;
56 splay(r,tot,0);
57 return;
58 }
59 bool find(int& r,int x){ //将值为x的节点旋转到根
60 R int now=r;
61 while(now){
62 if(v[now]==x){
63 splay(r,now,0);
64 return 1;
65 }else if(v[now]>x) now=ch[now][0];
66 else if(v[now]<x) now=ch[now][1];
67 }
68 return 0;
69 }
70 int getrnk(int& r,int x){
71 int ans=0;
72 R int now=r;
73 while(now){
74 if(v[now]==x){
75 if(ch[now][0]) ans+=siz[ch[now][0]];
76 splay(r,now,0);
77 return ans-1;
78 }else if(v[now]>x){
79 now=ch[now][0];
80 }else{
81 ans+=siz[ch[now][0]]+cnt[now];
82 now=ch[now][1];
83 }
84 }
85 return ans-1;
86 }
87 int getpre(int& r,int x){
88 R int now=r;
89 int ans=-oo,anspos=0;
90 while(now){
91 if(v[now]>=x){
92 now=ch[now][0];
93 }else{
94 if(v[now]>ans) ans=v[now],anspos=now;
95 now=ch[now][1];
96 }
97 }
98 if(anspos) splay(r,anspos,0);
99 return ans;
100 }
101 int getnxt(int& r,int x){
102 R int now=r;
103 int ans=oo,anspos=0;
104 while(now){
105 if(v[now]<=x){
106 now=ch[now][1];
107 }else{
108 if(v[now]<ans) ans=v[now],anspos=now;
109 now=ch[now][0];
110 }
111 }
112 if(anspos) splay(r,anspos,0);
113 return ans;
114 }
115 void getprenode(int& r){
116 R int now=ch[r][0],pre;
117 while(now) pre=now,now=ch[now][1];
118 splay(r,pre,r);
119 return;
120 }
121 void del(int &r,int x){
122 find(r,x);
123 if(cnt[r]>1){cnt[r]--;updata(r);return;}
124 if(!ch[r][0]&&!ch[r][1]){r=0;return;}
125 if(ch[r][0]&&!ch[r][1]){r=ch[r][0],fa[r]=0;return;}
126 if(!ch[r][0]&&ch[r][1]){r=ch[r][1],fa[r]=0;return;}
127 getprenode(r);
128 fa[ch[r][1]]=ch[r][0],ch[ch[r][0]][1]=ch[r][1];
129 r=ch[r][0],fa[r]=0;
130 updata(r);
131 return;
132 }
133 }splaytree;
134 struct Segtree{
135 void build(int k,int l,int r){
136 for(int i=l;i<=r;i++) splaytree.insert(root[k],a[i]);
137 splaytree.insert(root[k],-oo);splaytree.insert(root[k],oo);
138 ls[k]=l,rs[k]=r;
139 if(l==r) return;
140 int mid=(l+r)>>1;
141 build(k<<1,l,mid);
142 build(k<<1|1,mid+1,r);
143 return;
144 }
145 void modify(int k,int pos,int x){
146 splaytree.del(root[k],a[pos]);splaytree.insert(root[k],x);
147 if(ls[k]==rs[k]) return;
148 int mid=(ls[k]+rs[k])>>1;
149 if(pos<=mid) modify(k<<1,pos,x);
150 else modify(k<<1|1,pos,x);
151 return;
152 }
153 int quernk(int k,int ql,int qr,int x){
154 if(ls[k]==ql&&rs[k]==qr)
155 return splaytree.getrnk(root[k],x);
156 int mid=(ls[k]+rs[k])>>1;
157 if(qr<=mid) return quernk(k<<1,ql,qr,x);
158 else if(ql>mid) return quernk(k<<1|1,ql,qr,x);
159 else return quernk(k<<1,ql,mid,x)+quernk(k<<1|1,mid+1,qr,x);
160 }
161 int quekth(int ql,int qr,int x){
162 int l=0,r=oo,mid,res,ans;
163 while(l<=r){
164 mid=(l+r)>>1;
165 res=quernk(1,ql,qr,mid)+1;
166 if(res<=x) l=mid+1,ans=mid;
167 else r=mid-1;
168 }
169 return ans;
170 }
171 int quepre(int k,int ql,int qr,int x){
172 if(ls[k]==ql&&rs[k]==qr)
173 return splaytree.getpre(root[k],x);
174 int mid=(ls[k]+rs[k])>>1;
175 if(qr<=mid) return quepre(k<<1,ql,qr,x);
176 else if(ql>mid) return quepre(k<<1|1,ql,qr,x);
177 else return max(quepre(k<<1,ql,mid,x),quepre(k<<1|1,mid+1,qr,x));
178 }
179 int quenxt(int k,int ql,int qr,int x){
180 if(ls[k]==ql&&rs[k]==qr)
181 return splaytree.getnxt(root[k],x);
182 int mid=(ls[k]+rs[k])>>1;
183 if(qr<=mid) return quenxt(k<<1,ql,qr,x);
184 else if(ql>mid) return quenxt(k<<1|1,ql,qr,x);
185 else return min(quenxt(k<<1,ql,mid,x),quenxt(k<<1|1,mid+1,qr,x));
186 }
187 }segtree;
188 int main(){
189 R int opt,t1,t2,t3;
190 n=read(),m=read();
191 for(R int i=1;i<=n;i++) a[i]=read();
192 segtree.build(1,1,n);
193 for(R int i=1;i<=m;i++){
194 opt=read(),t1=read(),t2=read();
195 if(opt==1){
196 t3=read();
197 printf("%d\n",segtree.quernk(1,t1,t2,t3)+1);
198 }else if(opt==2){
199 t3=read();
200 printf("%d\n",segtree.quekth(t1,t2,t3));
201 }else if(opt==3){
202 segtree.modify(1,t1,t2);
203 a[t1]=t2;
204 }else if(opt==4){
205 t3=read();
206 printf("%d\n",segtree.quepre(1,t1,t2,t3));
207 }else{
208 t3=read();
209 printf("%d\n",segtree.quenxt(1,t1,t2,t3));
210 }
211 }
212 return 0;
213 }