BZOJ3224 CODEVS4543 普通平衡树 题解&代码
来源:互联网 发布:java使用线程池例子 编辑:程序博客网 时间:2024/06/11 21:46
醉啦醉啦= =第k大第k小纠结了好久,最后瞎蒙了一个蒙错了然后纠结了好久,后来学长告诉我【你们排名难道是成绩低的排前面么】
题意:
维护一个序列,按照val[]排序,支持:
1. 插入x
2. 删除x(若有多个相同的val,因只删除一个)
3. 查询x是第几大(若有多个相同的数,因输出最小的排名)
4. 查询第k大
5. 求x的前驱(前驱定义为小于x,且最大的数,可能树中不存在x)
6. 求x的后继(后继定义为大于x,且最小的数,同上)
思路:
维护一个顺序序列,维护s[]表示节点子树大小,z[]表示节点个数
求前驱后继的时候先插入一个再删除就行
#include<iostream>#include<stdio.h>#define lson ch[x][0]#define rson ch[x][1]using namespace std;const int maxn=100005;int n,op,x,tot,root,fa[maxn],ch[maxn][2],val[maxn],s[maxn],z[maxn];void link(int x,int y,int d){ if(y)ch[y][d]=x; if(x)fa[x]=y;}void maintain(int x){ if(x)s[x]=s[lson]+s[rson]+z[x];}int ischild(int x){ return ch[fa[x]][1]==x;}void rotate(int x){ int y=fa[x],d=ischild(x); if(!fa[y])root=x; link(x,fa[y],ischild(y)); link(ch[x][!d],y,d); link(y,x,!d); maintain(y);}void Splay(int x,int goal=0){ int y=fa[x],z=fa[y]; while(y!=goal) { if(z==goal) { rotate(x); break; } if(ischild(x)^ischild(y))rotate(x); else rotate(y); rotate(x); y=fa[x],z=fa[y]; } maintain(x);}int newnode(int v){ int t=++tot; val[t]=v; s[t]=z[t]=1; return t;}int getval(int value){ int x=root; while(x) { if(val[x]==value)return x; if(ch[x][val[x]<value])x=ch[x][val[x]<value]; else return x; } return x;}void addtree(int v){ if(!root) { root=newnode(v); return; } int x=getval(v),t=x; if(val[x]==v)z[x]++; else t=newnode(v),link(t,x,val[x]<v); Splay(t);}void deltree(int v){ int x=getval(v); if(z[x]>1) { z[x]--; Splay(x); return; } Splay(x); x=ch[x][0]; while(ch[x][1])x=ch[x][1]; if(x) { Splay(x,root); link(ch[root][1],x,1); root=x; fa[root]=0;//false } else { root=ch[root][1]; fa[root]=0; } maintain(root);}int getvalth(int v){ addtree(v); int x=getval(v); Splay(x); int ans=s[lson]+1; deltree(v); return ans;}int getkth(int k){ //cout<<k<<' '<<x<<endl; int x=root; while(x) { //cout<<ch[x][0]<<' '<<z[x]<<endl; if(k<=s[ch[x][0]])x=ch[x][0]; else if(k<=s[ch[x][0]]+z[x])return val[x]; else k-=s[ch[x][0]]+z[x],x=ch[x][1]; } //cout<<x<<endl; return val[x];}int getpre(int v){ addtree(v); int x=ch[root][0]; while(ch[x][1])x=ch[x][1]; deltree(v); return val[x];}int getnext(int v){ addtree(v); int x=ch[root][1]; while(ch[x][0])x=ch[x][0]; deltree(v); return val[x];}void print(int x){ if(ch[x][0])print(ch[x][0]); printf("%d %d\n",x,val[x]); if(ch[x][1])print(ch[x][1]);}int main(void){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&op,&x); //cout<<op<<endl; if(op==1) addtree(x); if(op==2) deltree(x); if(op==3) printf("%d\n",getvalth(x)); if(op==4) printf("%d\n",getkth(x)); if(op==5) printf("%d\n",getpre(x)); if(op==6) printf("%d\n",getnext(x)); //print(root); } return 0;}
0 0
- BZOJ3224 CODEVS4543 普通平衡树 题解&代码
- 【BZOJ3224】 【CODEVS4543】 普通平衡树 splay
- 【BZOJ3224】【codevs4543】【tyvj1728】普通平衡树,第一次的splay
- BZOJ3224普通平衡树splay,SBT代码
- [BZOJ3224]普通平衡树
- 【bzoj3224】普通平衡树
- bzoj3224普通平衡树
- BZOJ3224普通平衡树
- BZOJ3224 普通平衡树
- 【BZOJ3224】普通平衡树
- BZOJ3224普通平衡树
- Bzoj3224普通平衡树
- BZOJ3224 普通平衡树
- BZOJ3224 普通平衡树
- BZOJ3224 普通平衡树
- BZOJ3224 普通平衡树
- bzoj3224题解(普通平衡树的线段树解法)
- BZOJ3224[Tyvj 1728 普通平衡树]题解--Treap
- titlebar的使用步骤详细说明
- c++多个源文件共用一个全局变量(extern 的用法)
- 浮点数在计算机中的存储
- C++-字符串操作
- “Ceph浅析”系列之四Ceph的结构
- BZOJ3224 CODEVS4543 普通平衡树 题解&代码
- Git协作流程详解
- [Sqlserver] SQL Server Storage Engine: Data Pages and Data Rows
- Cocos2d_android你所需要知道的一切(下)
- Android 获取手机系统的声音设置管理通知提醒的声音
- Windows中快速在指定文件打开命令行
- Android 反射获得控件对象
- 总结
- 定制自己的BaseActivity