天天看點

樹套樹學習筆記樹套樹學習筆記

樹套樹學習筆記

吐槽一下:

其實感覺并沒有什麼好寫的,但好歹是個資料結構,不寫不好将題分類啊!

而且目前隻做了線段樹套平衡樹的題目,其它的就以後慢慢填坑吧! 其實就隻打了洛谷樹套樹模闆,QAQ部落客還是太弱了。

話說帶修改主席樹算不算樹狀數組套線段樹,部落客太弱了,請各位大佬解惑。

1.線段樹套平衡樹:

例題:洛谷P3380 【模闆】二逼平衡樹(樹套樹)

隻有第二個操作值得一說吧,不過也隻要二分數的大小,套用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 }      

轉載于:https://www.cnblogs.com/ljk123-de-bo-ke/p/11288144.html