bzoj 3224(splay/treap)
来源:互联网 发布:工业控制网络结构 编辑:程序博客网 时间:2024/05/02 14:26
传送门
慢的要死的splay,比别人的splay慢了至少30%。。。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=1e5+2;int ch[2][MAXN],f[MAXN],siz[MAXN],cnt[MAXN],key[MAXN];int sz,root;inline void clear(int x) { ch[0][x]=ch[1][x]=f[x]=siz[x]=cnt[x]=key[x]=0;}inline bool get(int x) { return ch[1][f[x]]==x;}inline void update(int x) { siz[x]=siz[ch[0][x]]+siz[ch[1][x]]+cnt[x];}inline void rotate(int x) { int old=f[x],oldf=f[old],which=get(x); ch[which][old]=ch[!which][x],f[ch[which][old]]=old,ch[!which][x]=old; f[old]=x,f[x]=oldf; if (oldf) ch[ch[1][oldf]==old][oldf]=x; update(old),update(x);}inline void splay(int x) { for (int fa;fa=f[x];rotate(x)) if (f[fa]) rotate(get(x)==get(fa)?fa:x); root=x;}inline void Insert(int x) { if (!root) { ++sz; ch[0][sz]=ch[1][sz]=f[sz]=0,root=sz,siz[sz]=cnt[sz]=1,key[sz]=x; return ; } int now=root,fa=0; while (1) { if (x==key[now]) { ++cnt[now],update(now),update(fa),splay(now); break; } fa=now; now=ch[key[now]<x][now]; if (!now) { ++sz; ch[0][sz]=ch[1][sz]=0,f[sz]=fa,siz[sz]=cnt[sz]=1; ch[key[fa]<x][fa]=sz,key[sz]=x; update(fa); splay(sz); break; } }}inline int rank(int x) { int now=root,ans=0; while (1) { if (x<key[now]) now=ch[0][now]; else { ans+=(ch[0][now]?siz[ch[0][now]]:0); if (x==key[now]) { splay(now); return ans+1; } ans+=cnt[now]; now=ch[1][now]; } }}inline int find(int x) { int now=root; while (1) { if (ch[0][now]&&x<=siz[ch[0][now]]) now=ch[0][now]; else { int temp=(ch[0][now]?siz[ch[0][now]]:0)+cnt[now]; if (x<=temp) return key[now]; x-=temp;now=ch[1][now]; } }}inline int pre() { int now=ch[0][root]; while (ch[1][now]) now=ch[1][now]; return now;}inline int nxt() { int now=ch[1][root]; while (ch[0][now]) now=ch[0][now]; return now;}inline void del(int x) { int must=rank(x); if (cnt[root]>1) {--cnt[root];update(root);return ;} if (!ch[0][root]&&!ch[1][root]) {clear(root);root=0;return ;} if (!ch[0][root]) { int oldroot=root; root=ch[1][root],f[root]=0,clear(oldroot); return ; } else if (!ch[1][root]) { int oldroot=root; root=ch[0][root],f[root]=0,clear(oldroot); return ; } int leftbig=pre(),oldroot=root; splay(leftbig); ch[1][root]=ch[1][oldroot]; f[ch[1][oldroot]]=root; clear(oldroot); update(root);}int main() {// freopen("bzoj 3224.in","r",stdin); int n,opt,x; scanf("%d",&n); for (register int i=0;i<n;++i) { scanf("%d%d",&opt,&x); switch (opt) { case 1:{Insert(x);break;} case 2:{del(x);break;} case 3:{printf("%d\n",rank(x));break;} case 4:{printf("%d\n",find(x));break;} case 5:{Insert(x);printf("%d\n",key[pre()]);del(x);break;} case 6:{Insert(x);printf("%d\n",key[nxt()]);del(x);break;} } } return 0;}
treap还勉强说得过去。
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;struct data{ int l,r,v,size,rnd,w;//左/右儿子,权值,子树大小,优先级,重复计数 data() {l=0,r=0,size=0,w=0;}}node[100004];int n,size,root,ans,opt,x;//x为权值inline int randad(){ static int seed=426; return seed=int(seed*48271LL%2147483647);}inline void update(int k) { node[k].size=node[node[k].l].size+node[node[k].r].size+node[k].w;}void rturn(int &k) { int t=node[k].l; node[k].l=node[t].r; node[t].r=k; node[t].size=node[k].size; update(k); k=t;}void lturn(int &k) { int t=node[k].r; node[k].r=node[t].l; node[t].l=k; node[t].size=node[k].size; update(k); k=t;}void insert(int &k,int x) { if (k==0) { k=++size; node[k].size=node[k].w=1,node[k].v=x,node[k].rnd=randad(); return; } ++node[k].size; if (x==node[k].v) ++node[k].w;//当前为位,重复计数一次 else if (x>node[k].v) {//插入右子树 insert(node[k].r,x); if (node[node[k].r].rnd<node[k].rnd) lturn(k); } else {//插入左子树 insert(node[k].l,x); if (node[node[k].l].rnd<node[k].rnd) rturn(k); } }void del(int &k,int x) { if (k==0) return; if (node[k].v==x) { if (node[k].w>1) {--node[k].w;--node[k].size;return;} if (!node[k].l||!node[k].r) k=node[k].l+node[k].r;//直接让儿子代替自己 else if (node[node[k].l].rnd<node[node[k].r].rnd) rturn(k),del(k,x); else lturn(k),del(k,x); } else if (x>node[k].v) --node[k].size,del(node[k].r,x);//处理右子树 else --node[k].size,del(node[k].l,x);//处理左子树 }int rank(int k,int x) {//数x排名第几 if (k==0) return 0; if (node[k].v==x) return node[node[k].l].size+1; else if (x>node[k].v) return node[node[k].l].size+node[k].w+rank(node[k].r,x); else return rank(node[k].l,x);}int num(int k,int x) {//排第x的是啥 if (k==0) return 0; if (x<=node[node[k].l].size) return num(node[k].l,x); else if (x>node[node[k].l].size+node[k].w) return num(node[k].r,x-node[node[k].l].size-node[k].w); else return node[k].v;}void pro(int k,int x) {//数x的前驱 if (k==0) return ; if (node[k].v<x) ans=k,pro(node[k].r,x); else pro(node[k].l,x);}void sub(int k,int x) {//数x的后继 if (k==0) return ; if (node[k].v>x) ans=k,sub(node[k].l,x); else sub(node[k].r,x);}int main() { scanf("%d",&n); for (int i=1;i<=n;++i) { scanf("%d%d",&opt,&x); switch(opt) { case 1:insert(root,x);break; case 2:del(root,x);break; case 3:printf("%d\n",rank(root,x));break; case 4:printf("%d\n",num(root,x));break; case 5:ans=0;pro(root,x);printf("%d\n",node[ans].v);break; case 6:ans=0;sub(root,x);printf("%d\n",node[ans].v);break; } } return 0;}
阅读全文
0 0
- bzoj 3224(splay/treap)
- bzoj 3223(非旋转treap/splay)
- [BZOJ 3224]普通平衡树(忽然想要存个模板 Treap/Splay)
- (bzoj 3224)<splay模板>
- BZOJ 1503 郁闷的出纳员 二叉平衡树(Treap,Splay)
- bzoj 1503 [NOI2004]郁闷的出纳员 平衡树(treap/Splay)
- bzoj 3224(非旋转treap)
- bzoj 3224(treap)
- BZOJ 3224 TREAP
- bzoj 3224 treap模板
- BZOJ 1056 [HAOI2008] 排名系统 Tire树+Treap(Splay)
- BZOJ 1208 浅谈treap+treap全操作模板(BZOJ 3224)
- BZOJ 3224 Splay
- [HNOI2002]营业额统计 (Splay || Treap)
- BZOJ 3224 TREAP 解题报告
- bzoj 3224 平衡树 treap
- BZOJ 3544 treap (set)
- [hdu4453]looploop [treap/splay]
- 正确显示textarea中输入的回车和空格
- 第三周项目三
- 摄影
- 51 nod 1737 配对(贡献)
- C++ MFC / VS2013 之十三(对话框:一般属性页对话框的创建及显示)
- bzoj 3224(splay/treap)
- ubuntu 16.04 amd64 libcrypto.so.1.o.o libssl.so.1.0.0
- MXNET学习笔记(二):模型的保存与加载
- 长寿的密码--从纪录片中进行搜索
- 新手学手机维修需要从那几个方面入手?
- java实现直接选择排序
- 第三周项目四
- Linux 目录结构及文件基本操作 【Linux】
- caffe学习(二) CIFAR-10数据集上训练