【BZOJ3224】【codevs4543】【tyvj1728】普通平衡树,第一次的splay
来源:互联网 发布:java 中间件 面试题 编辑:程序博客网 时间:2024/05/22 12:20
传送门1
传送门2
传送门3
写在前面:woc……woc……大家知道为什么这么久没写题解了吧
思路:不会用指针千万别用!千万别手贱多写函数!千万多调用splay!
感谢http://blog.csdn.net/leolin_/article/details/6436037
http://codevs.cn/wiki/solution/?problem_id=4543
solution16851
注意:数组版splay,个人不喜欢压行,代码写了4k,个人感觉思路还是蛮清晰的,没有特别的技巧,不推荐作为模板使用
代码:
#include"bits/stdc++.h"using namespace std;int n,root,tot;struct os{ int left,right,father,sz,occ,data;}a[300000];void ct(int root){ a[root].sz=a[root].occ+a[a[root].left].sz+a[a[root].right].sz;}void made(int x){ a[++tot].data=x; a[tot].sz=a[tot].occ=1;}void rotate(int x,bool flag){ int y=a[x].father; if (flag) { a[y].left=a[x].right; if (a[x].right) a[a[x].right].father=y; a[x].father=a[y].father; if (a[y].father) { if (a[a[y].father].left==y) a[a[y].father].left=x; else a[a[y].father].right=x; } a[x].right=y; a[y].father=x; } else { a[y].right=a[x].left; if (a[x].left) a[a[x].left].father=y; a[x].father=a[y].father; if (a[y].father) { if (a[a[y].father].left==y) a[a[y].father].left=x; else a[a[y].father].right=x; } a[x].left=y; a[y].father=x; } ct(y); ct(x);}void splay(int x,int goal){ int y; while (a[x].father!=goal) { y=a[x].father; if (a[y].father==goal) { if (a[y].left==x) rotate(x,1); else rotate(x,0); } else if (a[a[y].father].left==y) { if (a[y].left==x) rotate(y,1); else rotate(x,0); rotate(x,1); } else { if (a[y].right==x) rotate(y,0); else rotate(x,1); rotate(x,0); } } if (!goal) root=x;}void insert(int now,int x){ if (!root) {made(x);root=tot;return;} int flag=0; while (!flag) { a[now].sz++; if (a[now].data==x) a[now].occ++,flag=2; else if (a[now].data>x) { if (!a[now].left) made(x),a[now].left=tot,a[tot].father=now,flag=1; else now=a[now].left; } else { if (!a[now].right) made(x),a[now].right=tot,a[tot].father=now,flag=1; else now=a[now].right; } } splay((flag==1)?tot:now,0);}int find(int now,int x){ while (now) { if (a[now].data==x) {splay(now,0);return now;} else if (a[now].data>x) now=a[now].left; else now=a[now].right; } return 0;}int find_max(int now){ int pa=a[now].father; if (!now) return 0; while (a[now].right) now=a[now].right; splay(now,pa); return now;}int find_min(int now){ int pa=a[now].father; if (!now) return 0; while (a[now].left) now=a[now].left; splay(now,pa); return now;}int find_next_min(int x){ int ans=0,now=root; while (now) { if (a[now].data>=x) now=a[now].left; else ans=(a[now].data>a[ans].data||!ans)?now:ans,now=a[now].right; } splay(ans,0); return ans;}int find_next_max(int x){ int ans=0,now=root; while (now) { if (a[now].data<=x) now=a[now].right; else ans=(a[now].data<a[ans].data||!ans)?now:ans,now=a[now].left; } splay(ans,0); return ans;}bool del(int x){ int now=find(root,x); if (!now) return 0; splay(now,0); if (a[now].occ>1) { --a[now].occ; --a[now].sz; return 1; } if (!a[now].left&&!a[now].right) root=0; else if (!a[now].left) { root=a[now].right; a[a[now].right].father=0; } else if (!a[now].right) { root=a[now].left; a[a[now].left].father=0; } else { splay(find_max(a[now].left),root); a[a[now].left].right=a[now].right; a[a[now].right].father=a[now].left; a[a[now].left].father=0; root=a[now].left; ct(a[now].left); } ct(now); return 1;}int Kth(int k){ int now=root; int p; while (now) { p=a[a[now].left].sz; if (k>p&&k<=p+a[now].occ) break; if (k<=p) now=a[now].left; else k-=(p+a[now].occ),now=a[now].right; } splay(now,0); return now;}int find_rank(int x){ int ans=0,now=root; while (1) { if (x<a[now].data) now=a[now].left; else { if (x==a[now].data) { ans+=a[a[now].left].sz+1; break; } else ans+=a[a[now].left].sz+a[now].occ,now=a[now].right; } } splay(now,0); return ans;}main(){ scanf("%d",&n); for (int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); if (x==1) insert(root,y); else if (x==2) del(y); else if (x==3) printf("%d\n",find_rank(y)); else if (x==4) printf("%d\n",a[Kth(y)].data); else if (x==5) printf("%d\n",a[find_next_min(y)].data); else if (x==6) printf("%d\n",a[find_next_max(y)].data); }}
UPD
2017.3.23
学习后缀平衡树时搞了一发treap
#include<cstdio>#include<iostream>#include<cstdlib>#define ls(x) tr[x].ch[0]#define rs(x) tr[x].ch[1]#define son(x,y) tr[x].ch[y]#define M 100005using namespace std;int n,m,seed,root,cnt;int in(){ int t=0;char ch=getchar();bool f=0; while (ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') t=(t<<1)+(t<<3)+ch-48,ch=getchar(); return f?-t:t;} int ran(){ seed=seed^rand(); seed^=(seed<<7); seed^=(seed>>3); return seed;}struct Treap{ int key,fix,siz,occ,fa,ch[2]; void build(int Fa,int val) { key=val; fa=Fa; fix=ran(); siz=occ=1; ch[0]=ch[1]=0; }}tr[M];void count(int rt){ tr[rt].siz=tr[ls(rt)].siz+tr[rs(rt)].siz+tr[rt].occ;}void rotate(int x,bool f){ int y=tr[x].fa; son(y,!f)=son(x,f); if (son(x,f)) tr[son(x,f)].fa=y; tr[x].fa=tr[y].fa; if (tr[y].fa) if (ls(tr[y].fa)==y) ls(tr[y].fa)=x; else rs(tr[y].fa)=x; son(x,f)=y; tr[y].fa=x; count(y); count(x);}void insert(int rt,int val){ if (tr[rt].key==val) ++tr[rt].occ,++tr[rt].siz; else if (tr[rt].key>val) { if (ls(rt)) insert(ls(rt),val); else tr[ls(rt)=++cnt].build(rt,val); if (tr[ls(rt)].fix<tr[rt].fix) { if (!tr[rt].fa) root=ls(rt); rotate(ls(rt),1); } } else { if (rs(rt)) insert(rs(rt),val); else tr[rs(rt)=++cnt].build(rt,val); if (tr[rs(rt)].fix<tr[rt].fix) { if (!tr[rt].fa) root=rs(rt); rotate(rs(rt),0); } } count(rt);}void del(int rt,int val){ if (tr[rt].key==val) { if (tr[rt].occ>1) --tr[rt].occ,--tr[rt].siz; else if (!ls(rt)&&!rs(rt)) if (!tr[rt].fa) root=0; else { if (rt==ls(tr[rt].fa)) ls(tr[rt].fa)=0; else rs(tr[rt].fa)=0; } else if (!ls(rt)) if (!tr[rt].fa) root=rs(rt),tr[rs(rt)].fa=0; else { tr[rs(rt)].fa=tr[rt].fa; if (ls(tr[rt].fa)==rt) ls(tr[rt].fa)=rs(rt); else rs(tr[rt].fa)=rs(rt); } else if (!rs(rt)) if (!tr[rt].fa) root=ls(rt),tr[ls(rt)].fa=0; else { tr[ls(rt)].fa=tr[rt].fa; if (ls(tr[rt].fa)==rt) ls(tr[rt].fa)=ls(rt); else rs(tr[rt].fa)=ls(rt); } else { bool f=(tr[ls(rt)].fix<tr[rs(rt)].fix); int y=son(rt,!f); if (!tr[rt].fa) root=y; rotate(y,f); del(rt,val); count(y); } } else { if (tr[rt].key<val) del(rs(rt),val); else del(ls(rt),val); count(rt); }}int Rank(int val){ int x=root,ans=0; for (;;) if (tr[x].key==val) return ans+tr[ls(x)].siz+1; else if (tr[x].key<val) ans+=tr[ls(x)].siz+tr[x].occ,x=rs(x); else x=ls(x);}int Kth(int k){ int x=root; for (;;) if (tr[ls(x)].siz<k&&k<=tr[ls(x)].siz+tr[x].occ) return tr[x].key; else if (tr[ls(x)].siz>=k) x=ls(x); else k-=tr[ls(x)].siz+tr[x].occ,x=rs(x);}int Pre(int val){ int x=root,ans=-1<<30; for (;x;) if (tr[x].key<val) ans=max(ans,tr[x].key),x=rs(x); else x=ls(x); return ans;}int Sub(int val){ int x=root,ans=1<<30; for (;x;) if (tr[x].key>val) ans=min(ans,tr[x].key),x=ls(x); else x=rs(x); return ans;}main(){ srand(20170322); int opt,x; for (n=in();n;--n) { opt=in();x=in(); if (opt==1) { if (!root) tr[root=++cnt].build(0,x); else insert(root,x); } else if (opt==2) del(root,x); else if (opt==3) printf("%d\n",Rank(x)); else if (opt==4) printf("%d\n",Kth(x)); else if (opt==5) printf("%d\n",Pre(x)); else if (opt==6) printf("%d\n",Sub(x)); }}
0 0
- 【BZOJ3224】【codevs4543】【tyvj1728】普通平衡树,第一次的splay
- 【BZOJ3224】 【CODEVS4543】 普通平衡树 splay
- 【bzoj3224】【Tyvj1728】【普通平衡树】【splay】
- bzoj3224 Tyvj1728 普通平衡树
- 【BZOJ3224】Tyvj1728普通平衡树
- BZOJ3224 CODEVS4543 普通平衡树 题解&代码
- [TYVJ1728/BZOJ3224]普通平衡树-替罪羊树
- bzoj3224普通平衡树 Splay
- [BZOJ3224] 普通平衡树 - splay
- BZOJ3224 普通平衡树(splay)
- [BZOJ3224][SPLAY]普通平衡树
- [BZOJ3224]普通平衡树 SPlay
- bzoj3224普通平衡树splay
- 【Treap/非旋转Treap】BZOJ3224 [Tyvj1728]普通平衡树
- BZOJ3224 普通平衡树 Splay + 替罪羊树
- BZOJ3224普通平衡树splay,SBT代码
- bzoj3224 普通平衡树【splay版】
- 【bzoj3224】普通平衡树(splay板子)
- 删除字符串中字符数最少的字符
- HTTP中的Host字段
- 了解apache Hadoop--Hadoop最全生态系统介绍
- 使用AsyncTask异步加载类进行访问网络数据json的理解和用法
- matlab 滤波器设计
- 【BZOJ3224】【codevs4543】【tyvj1728】普通平衡树,第一次的splay
- Qgis国际化
- HDU 1050 Moving Tables 贪心!!
- 我们在平时或面试遇到这些问题时,我们应该怎么回答?
- opencv初探(一)
- ios 中汉字 转换 拼音
- 应用间跳转问题
- 机房重构---七层登录
- Hive 上下文分析 LAG LEAD