树套树学习笔记
树套树学习笔记
吐槽一下:
其实感觉并没有什么好写的,但好歹是个数据结构,不写不好将题分类啊!
而且目前只做了线段树套平衡树的题目,其它的就以后慢慢填坑吧! 其实就只打了洛谷树套树模板,QAQ博主还是太弱了。
话说带修改主席树算不算树状数组套线段树,博主太弱了,请各位大佬解惑。
1.线段树套平衡树:
只有第二个操作值得一说吧,不过也只要二分数的大小,套用1操作,看排名是否等于k了。
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 #define re register 4 using namespace std; 5 const int N=50006,M=1600006,inf=2147483647; 6 int n,m,t,t1,t2,t3,cnt=0,a[N],f[M],rnd[M],rt[N<<2],son[M][2],w[M],num[M],siz[M]; 7 inline int read(){ 8 int T=0,F=1; char ch=getchar(); 9 while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();} 10 while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar(); 11 return F*T; 12 } 13 inline void pushup(int x){siz[x]=siz[son[x][0]]+siz[son[x][1]]+num[x]; } 14 void rotate(int &u,int d) 15 { 16 int p=son[u][d^1]; son[u][d^1]=son[p][d]; son[p][d]=u; pushup(u); pushup(p); u=p; 17 } 18 int cmp(int u,int x) 19 { 20 if(w[u]==x) return -1; 21 return w[u]<x; 22 } 23 int ins(int &u,int x) 24 { 25 if(!u){u=++cnt; w[u]=x; rnd[u]=rand()%inf; siz[u]=1,num[u]=1; return cnt;} 26 else 27 { 28 ++siz[u]; 29 int d=cmp(u,x); 30 if(d==-1){++num[u]; return u;} 31 int oo=ins(son[u][d],x); 32 if(rnd[u]<rnd[son[u][d]]) rotate(u,d^1); 33 return oo; 34 } 35 } 36 void del(int &u,int x) 37 { 38 int d=cmp(u,x); 39 if(d==-1) 40 { 41 if(num[u]>1){--num[u],--siz[u]; return;} 42 if(!(son[u][0]*son[u][1])){u=son[u][0]+son[u][1]; return;} 43 else 44 { 45 int d2=(rnd[son[u][0]]>rnd[son[u][1]]?1:0); 46 rotate(u,d2); del(son[u][d2],x); 47 } 48 } 49 else del(son[u][d],x); 50 pushup(u); 51 } 52 int pre(int u,int x) 53 { 54 int d=cmp(u,x); 55 if(!u) return -inf; 56 if(d==-1) return pre(son[u][0],x); 57 if(d) return max(pre(son[u][1],x),w[u]); 58 return pre(son[u][0],x); 59 } 60 int nxt(int u,int x) 61 { 62 int d=cmp(u,x); 63 if(!u) return inf; 64 if(d==-1) return nxt(son[u][1],x); 65 if(!d) return min(nxt(son[u][0],x),w[u]); 66 return nxt(son[u][1],x); 67 } 68 int rnk(int x,int y){ 69 int sum=0,z=rt[y]; 70 while(z){ 71 if(w[z]==x) return sum+siz[son[z][0]]; 72 if(w[z]>x) z=son[z][0]; 73 else sum+=siz[son[z][0]]+num[z],z=son[z][1]; 74 } 75 return sum; 76 } 77 void build(int l,int r,int x){ 78 for(int i=l;i<=r;++i) ins(rt[x],a[i]); 79 if(l==r) return; 80 int mid=((l+r)>>1); 81 build(l,mid,x<<1),build(mid+1,r,x<<1|1); 82 } 83 int query_rank(int l,int r,int p,int q,int x,int k){ 84 if(p<=l&&r<=q) return rnk(k,x); 85 int mid=((l+r)>>1); 86 if(p>mid) return query_rank(mid+1,r,p,q,x<<1|1,k); 87 if(q<=mid) return query_rank(l,mid,p,q,x<<1,k); 88 return query_rank(l,mid,p,q,x<<1,k)+query_rank(mid+1,r,p,q,x<<1|1,k); 89 } 90 int query_num(int l,int r,int p,int q,int x){ 91 if(l==r) return l; 92 int mid=((l+r+1)>>1); 93 if(query_rank(1,n,p,q,1,mid)+1>x) return query_num(l,mid-1,p,q,x); 94 else return query_num(mid,r,p,q,x); 95 } 96 void query_update(int l,int r,int p,int x,int y){ 97 del(rt[x],a[p]); ins(rt[x],y); 98 int mid=((l+r)>>1); 99 if(l==r){a[p]=y; return;} 100 if(p<=mid) query_update(l,mid,p,x<<1,y); 101 else query_update(mid+1,r,p,x<<1|1,y); 102 } 103 int query_pre(int l,int r,int p,int q,int x,int y){ 104 if(p<=l&&r<=q){t1=ins(rt[x],y),t2=pre(rt[x],y),del(rt[x],y); return t2;} 105 int mid=((l+r)>>1); 106 if(q<=mid) return query_pre(l,mid,p,q,x<<1,y); 107 if(p>mid) return query_pre(mid+1,r,p,q,x<<1|1,y); 108 return max(query_pre(l,mid,p,q,x<<1,y),query_pre(mid+1,r,p,q,x<<1|1,y)); 109 } 110 int query_nxt(int l,int r,int p,int q,int x,int y){ 111 if(p<=l&&r<=q){t1=ins(rt[x],y),t2=nxt(rt[x],y),del(rt[x],y); return t2;} 112 int mid=((l+r)>>1); 113 if(q<=mid) return query_nxt(l,mid,p,q,x<<1,y); 114 if(p>mid) return query_nxt(mid+1,r,p,q,x<<1|1,y); 115 return min(query_nxt(l,mid,p,q,x<<1,y),query_nxt(mid+1,r,p,q,x<<1|1,y)); 116 } 117 int main(){ 118 srand(time(NULL)); 119 n=read(),m=read(); 120 for(re int i=1;i<=n;++i) a[i]=read(); 121 build(1,n,1); 122 for(re int i=1;i<=m;++i){ 123 t=read(),t1=read(),t2=read(); 124 switch(t){ 125 case 1:t3=read();printf("%d\n",query_rank(1,n,t1,t2,1,t3)+1);break; 126 case 2:t3=read();printf("%d\n",query_num(0,1e8,t1,t2,t3));break; 127 case 3:query_update(1,n,t1,1,t2);break; 128 case 4:t3=read();printf("%d\n",query_pre(1,n,t1,t2,1,t3));break; 129 case 5:t3=read();printf("%d\n",query_nxt(1,n,t1,t2,1,t3));break; 130 } 131 } 132 return 0; 133 }