P3369-[模板]普通平衡树【无旋Treap】
生活随笔
收集整理的這篇文章主要介紹了
P3369-[模板]普通平衡树【无旋Treap】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P3369
題目大意
一個空可重集,要求支持
- 插入一個數xxx
- 刪除一個數xxx
- 詢問一個數xxx的排名
- 詢問排名第xxx的數字
- 詢問xxx的前驅
- 詢問xxx的后繼
1≤n≤105,1≤∣x∣≤1071\leq n\leq 10^5,1\leq |x|\leq 10^71≤n≤105,1≤∣x∣≤107
解題思路
拖了兩年的FHQ終于還是寫了(還有二逼平衡樹拖到現在還沒寫)。
看的是別人博客學的:https://www.luogu.com.cn/blog/85514/fhq-treap-xue-xi-bi-ji
具體特點就是結構固定我通過分裂的方式直接讓節點插入在對應的位置,這樣就不需要旋轉來調整結構了。
還有相同的數字不是存在同一個節點而是分開存的,所以同一個數字可以有多個節點。
時間復雜度:O(nlog?n)O(n\log n)O(nlogn)
code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+10; int T,root; struct FHQ{int cnt,w[N],rnk[N],siz[N],t[N][2];int NewNode(int val){w[++cnt]=val;siz[cnt]=1;rnk[cnt]=rand();return cnt;}void PushUp(int x){siz[x]=siz[t[x][0]]+siz[t[x][1]]+1;return;}void Split(int &x,int &y,int p,int val){if(!p){x=y=0;return;}if(w[p]<=val)x=p,Split(t[x][1],y,t[p][1],val);else y=p,Split(x,t[y][0],t[p][0],val);PushUp(p);return;}int Merge(int x,int y){if(!x||!y)return x|y;if(rnk[x]<rnk[y]){t[x][1]=Merge(t[x][1],y);PushUp(x);return x;}else{t[y][0]=Merge(x,t[y][0]);PushUp(y);return y;}}int Find(int x,int k){if(siz[t[x][0]]>=k)return Find(t[x][0],k);if(siz[t[x][0]]+1==k)return x;return Find(t[x][1],k-siz[t[x][0]]-1);}void Insert(int w){int x,y;Split(x,y,root,w);root=Merge(Merge(x,NewNode(w)),y);}void Delete(int w){int x,y,z;Split(x,y,root,w-1);Split(y,z,y,w);y=Merge(t[y][0],t[y][1]);root=Merge(Merge(x,y),z);return;}int GetRank(int w){int x,y,ans;Split(x,y,root,w-1);ans=siz[x]+1;root=Merge(x,y);return ans;}int GetVal(int r){return w[Find(root,r)];}int GetPre(int r){int x,y,ans;Split(x,y,root,r-1);ans=w[Find(x,siz[x])];root=Merge(x,y);return ans;}int GetNxt(int r){int x,y,ans;Split(x,y,root,r);ans=w[Find(y,1)];root=Merge(x,y);return ans;} }Tr; int main() {scanf("%d",&T);Tr.NewNode(-1e9);Tr.NewNode(1e9);root=Tr.Merge(1,2);while(T--){int op,w;scanf("%d%d",&op,&w);if(op==1)Tr.Insert(w);else if(op==2)Tr.Delete(w);else if(op==3)printf("%d\n",Tr.GetRank(w)-1);else if(op==4)printf("%d\n",Tr.GetVal(w+1));else if(op==5)printf("%d\n",Tr.GetPre(w));else if(op==6)printf("%d\n",Tr.GetNxt(w));} } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的P3369-[模板]普通平衡树【无旋Treap】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ai怎么临摹图片(ai怎么临摹图片文字)
- 下一篇: P3835-[模板]可持久化平衡树【无旋