400字范文,内容丰富有趣,生活中的好帮手!
400字范文 > P3369-[模板]普通平衡树【无旋Treap】

P3369-[模板]普通平衡树【无旋Treap】

时间:2019-06-05 08:09:54

相关推荐

P3369-[模板]普通平衡树【无旋Treap】

正题

题目链接:/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终于还是写了(还有二逼平衡树拖到现在还没写)。

看的是别人博客学的:/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));}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。