3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 11427  Solved: 4878
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
数据如下http://pan.baidu.com/s/1jHMJwO2

Source

平衡树

#include <cstdio>
#define Maxn 1000000
using namespace std;
int f[Maxn];//father
int ch[Maxn][2];//child ; 0 for left ; 1 for right
int key[Maxn];//key
int cnt[Maxn];//value
int siz[Maxn];//size of subtree
int sz,root;//size of tree and root
//clear the ndoevoid clear(int x)
{ch[x][0]=ch[x][1]=f[x]=cnt[x]=key[x]=siz[x]=0;
}//rightson return 1;left son return 0
int getson(int x)
{return ch[f[x]][1]==x;
}//update the size
void update(int x)
{siz[x]=cnt[x];if (ch[x][0]) siz[x]+=siz[ch[x][0]];if (ch[x][1]) siz[x]+=siz[ch[x][1]];
}//retation
int rotate(int x)
{int fa=f[x],fafa=f[fa],k=getson(x);ch[fa][k]=ch[x][k^1];f[ch[fa][k]]=fa;ch[x][k^1]=fa;f[fa]=x;f[x]=fafa;if (fafa)ch[fafa][ch[fafa][1]==fa]=x;update(fa);update(x);
}//rotate until x is the root
void splay(int x)
{for (int fa;fa=f[x];rotate(x))if (f[fa])rotate(getson(x)==getson(fa) ? fa : x);root=x;
}int pre()
{int now=ch[root][0];while(ch[now][1])now=ch[now][1];return now;
}int nex()
{int now=ch[root][1];while(ch[now][0])now=ch[now][0];return now;
}//find x's pos
int findpos(int v)
{int now=root,ans=0;while(1){if (v<key[now])now=ch[now][0];else{ans+=ch[now][0]?siz[ch[now][0]]:0;if (v==key[now]) {splay(now);return ans+1;}ans+=cnt[now];now=ch[now][1];}}
}//find pos's x
int findx(int x)
{int now=root;while(1){if (ch[now][0] && x<=siz[ch[now][0]])now=ch[now][0];else{int temp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now];if (x<=temp)return key[now];x-=temp;now=ch[now][1];}}
}//ceate a new splay node
void create(int v)
{sz++;ch[sz][0]=ch[sz][1]=f[sz]=0;key[sz]=v;cnt[sz]=1;siz[sz]=1;//root=sz;
}//insert a node
void insert(int v)
{if (!root)create(v),root=sz;else{int now=root,fa=0;while(1){if (key[now]==v){cnt[now]++;update(now);update(fa);splay(now);break;}fa=now;now=ch[fa][v>key[fa]];if (!now){create(v);f[sz]=fa;ch[fa][v>key[fa]]=sz;update(fa);splay(sz);break;}}}
}void del(int x)
{int t=findpos(x);if (cnt[root]>1) {cnt[root]--;update(root);return;}//noneif (!ch[root][0] && !ch[root][1]){clear(root);root=0;return;}//oneif (!ch[root][1]){int temp=root;root=ch[root][0];f[root]=0;clear(temp);return;}elseif (!ch[root][0]){int temp=root;root=ch[root][1];f[root]=0;clear(temp);return;}//twoint pre1=pre(),temp=root;splay(pre1);f[ch[temp][1]]=root;ch[root][1]=ch[temp][1];clear(temp);update(root);
}int main()
{  int n,opt,x;  scanf("%d",&n);  for (int i=1;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",findpos(x)); break;  case 4: printf("%d\n",findx(x)); break;  case 5: insert(x); printf("%d\n",key[pre()]); del(x); break;case 6: insert(x); printf("%d\n",key[nex()]); del(x); break;}  }
}

#include<iostream>
#include<cstdio>
#include<cstring>#define N 1000000using namespace std;
int f[N],ch[N][2],key[N],cnt[N],siz[N],sz,root;inline int read()
{int x=0,f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}inline void update(int x)
{siz[x]=cnt[x];if(ch[x][0]) siz[x]+=siz[ch[x][0]];if(ch[x][1]) siz[x]+=siz[ch[x][1]];
}int pre()
{int now=ch[root][0];while(ch[now][1]) now=ch[now][1];return now;
}int nex()
{int now=ch[root][1];while(ch[now][0]) now=ch[now][0];return now;
}inline int getson(int x)
{return ch[f[x]][1]==x;
}inline void rorate(int x)
{int fa=f[x],ffa=f[fa],k=getson(x);ch[fa][k]=ch[x][k^1];f[ch[fa][k]]=fa;ch[x][k^1]=fa;f[fa]=x;f[x]=ffa;if(ffa)ch[ffa][ch[ffa][1]==fa]=x;update(fa);update(x);
}void splay(int x)
{for(int fa;fa=f[x];rorate(x))if(f[fa]) rorate(getson(x)==getson(fa)?fa:x);root=x;
}int findpos(int x)
{int now=root,ans=0;while(1){if(x<key[now]) now=ch[now][0];else {ans+=ch[now][0]?siz[ch[now][0]]:0;if(x==key[now]){splay(now);return ans+1;}ans+=cnt[now];now=ch[now][1];}}
}int findx(int x)
{int now=root;while(1){if(ch[now][0]&&x<=siz[ch[now][0]]) now=ch[now][0];else{int tmp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now];if(x<=tmp) return key[now];x-=tmp;now=ch[now][1];}}
}void clear(int x)
{ch[x][0]=ch[x][1]=cnt[x]=siz[x]=key[x]=f[x]=0;
}void creat(int x)
{sz=sz+1;key[sz]=x;cnt[sz]=siz[sz]=1;ch[sz][0]=ch[sz][1]=f[sz]=0;
}void insert(int x)
{if(!root) creat(x),root=sz;else{int now=root,fa=0;while(1){if(key[now]==x){cnt[now]++;siz[now]++;splay(now);break;}fa=now;now=ch[fa][x>key[fa]];if(!now){creat(x);f[sz]=fa;ch[fa][x>key[fa]]=sz;splay(sz);break;}}}
}void del(int x)
{int t=findpos(x);if(cnt[root]>1){cnt[root]--;siz[root]--;return;}if(!ch[root][0]&&!ch[root][1]){clear(root);root=0;return;}if(!ch[root][0]){int tmp=root;root=ch[root][1];f[root]=0;clear(tmp);return;}if(!ch[root][1]){int tmp=root;root=ch[root][0];f[root]=0;clear(tmp);return;}int pre1=pre(),tmp=root;splay(pre1);ch[root][1]=ch[tmp][1];f[ch[tmp][1]]=root;clear(tmp);update(root);
}int main()
{int n,opt,x;n=read();for(int i=1;i<=n;i++){opt=read();x=read();switch(opt){case 1 :insert(x);break;case 2 :del(x);break; case 3 :printf("%d\n",findpos(x));break;case 4 :printf("%d\n",findx(x));break;case 5 :insert(x);printf("%d\n",key[pre()]);del(x);break;case 6 :insert(x);printf("%d\n",key[nex()]);del(x);break; }}
}

我的马蜂

转载于:https://www.cnblogs.com/L-Memory/p/6556921.html

bzoj3224 普通平衡树(splay 模板)相关推荐

  1. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  2. 史上最详尽的平衡树(splay)讲解与模板

    首先声明:万分感谢gty大哥的帮助!这年头能找到简单易懂的数组版平衡树模板只能靠学长了! 变量声明:f[i]表示i的父结点,ch[i][0]表示i的左儿子,ch[i][1]表示i的右儿子,key[i] ...

  3. hihocoder #1329 : 平衡树·Splay

    #1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...

  4. 平衡树(Splay) 服务:第一弹——旋转的艺术

    平衡树(Splay) 服务:第一弹--旋转的艺术 0.前言 本蒟蒻前不久刚学SPLAY,有了一点心得,想要巩固下来.同时也觉得网上的神犇们实在太强了,有的内容并不能很好的让我这样的蒟蒻理解,因此便有了 ...

  5. BZOJ 3223: Tyvj 1729 文艺平衡树-Splay树(区间翻转)模板题

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 6881  Solved: 4213 [Submit][S ...

  6. bzoj3224: Tyvj 1728 普通平衡树(splay)

    3224: Tyvj 1728 普通平衡树 题目:传送门 题解: 啦啦啦啦又来敲个模版水经验啦~ 代码: 1 #include<cstdio> 2 #include<cstring& ...

  7. 【BZOJ - 3224】普通平衡树(Splay模板题)

    题干: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的数,因输出最 ...

  8. 伸展树 Splay 模板

    学习Splay的时候参考了很多不同的资料,然而参考资料太杂的后果就是模板调出来一直都有问题,尤其是最后发现网上找的各种资料均有不同程度的错误. 好在啃了几天之后终于算是啃下来了. Splay也算是平衡 ...

  9. 文艺平衡树 Splay 学习笔记(1)

    (这里是Splay基础操作,reserve什么的会在下一篇里面讲) 好久之前就说要学Splay了,结果苟到现在才学习. 可能是最近良心发现自己实在太弱了,听数学又听不懂只好多学点不要脑子的数据结构. ...

  10. BZOJ 3223: Tyvj 1729 文艺平衡树(splay)

    速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...

最新文章

  1. pandas loc()与iloc用法
  2. css案例学习之全局声明*{} 与body{}的区别
  3. 2017计算机应用类专业综合知识试题,对口高考2017计算机应用类专业综合模拟题.doc...
  4. 在mojoportal项目中发邮件使用的是dotnetopenmail
  5. Docker - 实战TLS加密通讯
  6. 程序员修复一个bug的心路历程,太形象了
  7. [ES6] 细化ES6之 -- 前端模块化
  8. 基于 HTML5 Canvas 实现的文字动画特效
  9. C语言 const、volatile、const volatile限定符理解
  10. bootstrap-徽章-链接
  11. 基于 wke 的浏览器:如何实现 js 和 c++ 的互相调用
  12. 两万字的CAPL语法基础,一篇文章带你入门
  13. 《穿越计算机的迷雾》
  14. IDEA插件开发(简单案例助你快速入门)
  15. 透明图片下载求全透明png图片_微信“全透明”模式,让你的微信真正实现隐身效果!...
  16. access连接mysql很慢_怎么解决ACCESS数据库太大造成运行慢的问题?
  17. 音乐播放器mplayer的简单使用
  18. sql server 自定义背景、字体及显示行数
  19. GC.SuppressFinalize()的正确用法
  20. HEVC(h265)学习

热门文章

  1. springboot自动配置的原理
  2. 将网站转换为应用程序的软件—“Unite”
  3. GreenOpenPaint简介
  4. esayUI实践的一些体会
  5. struts+spring action应配置为scope=prototype
  6. discuz 任务扩展
  7. Weld(CDI)教程
  8. 一个类windows系统的效果图
  9. 一起谈.NET技术,在.NET中嵌入IronPython 交互
  10. [JNI]开发之旅 (3)jni域描述符说明