【模板】二逼平衡树
线段树套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 }