日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

【bzoj3224】 Tyvj1728—普通平衡树

發(fā)布時(shí)間:2025/7/14 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【bzoj3224】 Tyvj1728—普通平衡树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.lydsy.com/JudgeOnline/problem.php?id=3224?(題目鏈接)

題意

  1. 插入x數(shù);2. 刪除x數(shù)(若有多個(gè)相同的數(shù),因只刪除一個(gè));3. 查詢x數(shù)的排名(若有多個(gè)相同的數(shù),因輸出最小的排名);4. 查詢排名為x的數(shù);5. 求x的前驅(qū)(前驅(qū)定義為小于x,且最大的數(shù));6. 求x的后繼(后繼定義為大于x,且最小的數(shù))

Solution

  treap板子。右轉(zhuǎn)光勛總結(jié)→_→:平衡樹(shù)

細(xì)節(jié)

  一個(gè)節(jié)點(diǎn)還統(tǒng)計(jì)了這個(gè)數(shù)出現(xiàn)了幾次,然后詢問(wèn)排名前驅(qū)后繼什么的寫(xiě)的我蛋都要碎了T_T,所以這里旋轉(zhuǎn)版的rank求的是小于$x$的數(shù)的個(gè)數(shù),而不是$x$的排名。

旋轉(zhuǎn)treap

// bzoj3224 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout) using namespace std;const int maxn=100010; int n,sz,Dargen; struct node {int son[2],size,val,rnd,w;int& operator [] (int x) {return son[x];} }tr[maxn];void pushup(int k) {tr[k].size=tr[tr[k][0]].size+tr[tr[k][1]].size+tr[k].w; } void rotate(int &x,int p) { //記得&int y=tr[x][p];tr[x][p]=tr[y][p^1];tr[y][p^1]=x;x=y; //記得寫(xiě)x=ypushup(tr[y][p^1]);pushup(y); } void insert(int &k,int x) {if (!k) {tr[k=++sz].val=x;tr[k].rnd=rand();tr[k].size=tr[k].w=1;return;}int p=x>tr[k].val;tr[k].size++;if (tr[k].val==x) {tr[k].w++;return;}insert(tr[k][p],x);if (tr[tr[k][p]].rnd>tr[k].rnd) rotate(k,p); } void erase(int &k,int x) {if (k==0) return;if (tr[k].val==x) {if (tr[k].w>1) {tr[k].w--;tr[k].size--;return;}if (tr[k][0]*tr[k][1]==0) k=tr[k][0]+tr[k][1];else rotate(k,tr[tr[k][0]].rnd<tr[tr[k][1]].rnd),erase(k,x);}else tr[k].size--,erase(tr[k][x>tr[k].val],x); } int find(int k,int x) {if (!k) return 0;if (tr[tr[k][0]].size<x && x<=tr[tr[k][0]].size+tr[k].w) return tr[k].val;else if (x<=tr[tr[k][0]].size) return find(tr[k][0],x);else return find(tr[k][1],x-tr[tr[k][0]].size-tr[k].w); } int rank(int k,int x) {if (!k) return 0;if (x<=tr[k].val) return rank(tr[k][0],x);else return rank(tr[k][1],x)+tr[tr[k][0]].size+tr[k].w; } int main() {scanf("%d",&n);for (int op,x,i=1;i<=n;i++) {scanf("%d%d",&op,&x);if (op==1) insert(Dargen,x);if (op==2) erase(Dargen,x);if (op==3) printf("%d\n",rank(Dargen,x)+1);if (op==4) printf("%d\n",find(Dargen,x));if (op==5) printf("%d\n",find(Dargen,rank(Dargen,x)));if (op==6) printf("%d\n",find(Dargen,rank(Dargen,x+1)+1));}return 0; }

非旋轉(zhuǎn)treap

// bzoj3224 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std;const int maxn=100010; int n,sz,Dargen; struct node {int son[2],size,val,rnd;int& operator [] (int x) {return son[x];} }tr[maxn];void pushup(int k) {tr[k].size=tr[tr[k][0]].size+tr[tr[k][1]].size+1; } void split(int k,int x,int &a,int &b) {if (!x) {a=0;b=k;return;}int l=tr[k][0],r=tr[k][1];if (tr[l].size==x) tr[k][0]=0,a=l,b=k;else if (tr[l].size+1==x) tr[k][1]=0,a=k,b=r;else if (x<tr[l].size) split(l,x,a,tr[k][0]),b=k;else split(r,x-tr[l].size-1,tr[k][1],b),a=k;pushup(k); } int merge(int x,int y) { //按順序x<yif (!x || !y) return x|y;if (tr[x].rnd>tr[y].rnd) {tr[x][1]=merge(tr[x][1],y);pushup(x);return x;}else {tr[y][0]=merge(x,tr[y][0]);pushup(y);return y;} } int rank(int k,int x) {if (!k) return 1;if (x<=tr[k].val) return rank(tr[k][0],x);else return rank(tr[k][1],x)+tr[tr[k][0]].size+1; } int find(int k,int x) {if (!k) return 0;if (tr[tr[k][0]].size+1==x) return tr[k].val;else if (x<=tr[tr[k][0]].size) return find(tr[k][0],x);else return find(tr[k][1],x-tr[tr[k][0]].size-1); } void insert(int x) {int l,r;tr[++sz].val=x;tr[sz].rnd=rand();tr[sz].size=1;split(Dargen,rank(Dargen,x)-1,l,r);Dargen=merge(merge(l,sz),r); } void erase(int k) {int x,y;split(Dargen,k,x,y);split(x,k-1,x,k);Dargen=merge(x,y); } int main() {scanf("%d",&n);for (int op,x,i=1;i<=n;i++) {scanf("%d%d",&op,&x);if (op==1) insert(x);if (op==2) erase(rank(Dargen,x));if (op==3) printf("%d\n",rank(Dargen,x));if (op==4) printf("%d\n",find(Dargen,x));if (op==5) printf("%d\n",find(Dargen,rank(Dargen,x)-1));if (op==6) printf("%d\n",find(Dargen,rank(Dargen,x+1)));}return 0; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/MashiroSky/p/6486539.html

總結(jié)

以上是生活随笔為你收集整理的【bzoj3224】 Tyvj1728—普通平衡树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。