算法复习——splay(bzoj3224)
题目:
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
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
84185
492737
HINT
题解:
splay模板题···表示两周没碰键盘手都生了····
代码:
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cmath>
- #include<ctime>
- #include<cctype>
- #include<cstring>
- #include<string>
- #include<algorithm>
- using namespace std;
- const int N=;
- int root,size[N],son[N][],key[N],cnt[N],tot,father[N];
- int a,b,n;
- inline void clear(int now)
- {
- size[now]=son[now][]=son[now][]=key[now]=cnt[now]=father[now]=;
- }
- inline void update(int now)
- {
- if(now)
- {
- size[now]=cnt[now];
- if(son[now][]) size[now]+=size[son[now][]];
- if(son[now][]) size[now]+=size[son[now][]];
- }
- }
- inline int get(int a)
- {
- return son[father[a]][]==a;
- }
- inline void rotate(int now)
- {
- int fa=father[now],ofa=father[fa],which=get(now);
- son[fa][which]=son[now][which^],father[son[fa][which]]=fa;
- son[now][which^]=fa,father[fa]=now,father[now]=ofa;
- if(ofa) son[ofa][son[ofa][]==fa]=now;
- update(fa),update(now);
- }
- inline void splay(int now)
- {
- while(father[now])
- {
- if(father[father[now]]) rotate(get(now)==get(father[now])?father[now]:now);
- rotate(now);
- }
- root=now;
- }
- inline void insert(int x)
- {
- int now=root,last=;
- while(true)
- {
- if(!now)
- {
- now=++tot;size[now]=cnt[now]=;father[now]=last;key[now]=x;
- son[last][key[now]>key[last]]=now;update(last);splay(now);
- break;
- }
- if(key[now]==x)
- {
- cnt[now]++;update(now);update(last);splay(now);
- break;
- }
- last=now;now=son[now][x>key[now]];
- }
- }
- inline int find(int x)
- {
- int now=root,ans=;
- while(true)
- {
- if(x<key[now]) now=son[now][];
- else
- {
- ans+=size[son[now][]];
- if(x==key[now]) {splay(now);return ans+;}
- ans+=cnt[now];now=son[now][];
- }
- }
- }
- inline int findx(int x)
- {
- int now=root;
- while(true)
- {
- if(x<=size[son[now][]]) now=son[now][];
- else
- {
- int temp=size[son[now][]]+cnt[now];
- if(x<=temp) return key[now];
- x-=temp;now=son[now][];
- }
- }
- }
- inline int pre()
- {
- int now=son[root][];
- while(son[now][]) now=son[now][];
- return now;
- }
- inline int next()
- {
- int now=son[root][];
- while(son[now][]) now=son[now][];
- return now;
- }
- inline void Delete(int x)
- {
- int nothing=find(x);
- if(cnt[root]>) {cnt[root]--;return;}
- else if(!son[root][]&&!son[root][])
- {clear(root);root=;return;}
- else if(!son[root][])
- {int oldroot=root;root=son[root][];father[root]=;clear(oldroot);return;}
- else if(!son[root][])
- {int oldroot=root;root=son[root][];father[root]=;clear(oldroot);return;}
- else
- {
- int leftbig=pre(),oldroot=root;
- splay(leftbig);son[root][]=son[oldroot][];
- father[son[root][]]=root;clear(oldroot);
- update(root);
- return;
- }
- }
- inline int findpre(int x)
- {
- insert(x);int temp=pre();
- Delete(x);return key[temp];
- }
- inline int findnext(int x)
- {
- insert(x);int temp=next();
- Delete(x);return key[temp];
- }
- int main()
- {
- //freopen("a.in","r",stdin);
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- {
- scanf("%d%d",&a,&b);
- if(a==)
- insert(b);
- if(a==)
- Delete(b);
- if(a==)
- {
- int temp=find(b);
- printf("%d\n",temp);
- }
- if(a==)
- {
- int temp=findx(b);
- printf("%d\n",temp);
- }
- if(a==)
- {
- int temp=findpre(b);
- printf("%d\n",temp);
- }
- if(a==)
- {
- int temp=findnext(b);
- printf("%d\n",temp);
- }
- }
- return ;
- }
算法复习——splay(bzoj3224)的更多相关文章
- 算法复习——splay+启发式合并(bzoj2733-永无乡)
题目: Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通 ...
- C#冒泡算法复习
C#冒泡算法复习 冒泡算法的意思:每一趟找到一个最小或最大的数放到最后面,比较总数的n-1次(因为比较是2个双双比较的) 第一层循环表示进行比较的次数,总共要比较(数的)-1次 (因为比较是2个双双比 ...
- C语言排序算法复习
排序算法有很多种,这里在复习和分析的基础上,做一个自己的总结: 首先要知道有哪些排序算法,google一下,有云C语言7大经典排序算法(也有8大).主要包括冒泡排序,快速排序,选择排序,插入排序,希尔 ...
- KMP算法复习【+继续学习】
离NOIP还剩12天,本蒟蒻开始准备复习了. 先来个KMP[似乎我并没有写过KMP的blog] KMP KMP算法是解决字符串匹配问题的一个算法,主要是单对单的字符串匹配加速,时间复杂度O(m + n ...
- 算法复习周------“动态规划之‘最长公共子序列’”&&《计蒜课》---最长公共子串题解
问题描述: 这个问题其实很容易理解.就是给你两个序列X={x1,x2,x3......xm} Y={y1,y2,y3......ym},要求找出X和Y的一个最长的公共子序列. 例:Xi={A, B, ...
- [算法] 数据结构 splay(伸展树)解析
前言 splay学了已经很久了,只不过一直没有总结,鸽了好久来写一篇总结. 先介绍 splay:亦称伸展树,为二叉搜索树的一种,部分操作能在 \(O( \log n)\) 内完成,如插入.查找.删除. ...
- K-Means聚类和EM算法复习总结
摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 k-means算法是一种得到最广泛使用的聚类算法. 它是将各个聚类子集内 ...
- 通过“回文字算法”复习C++语言。
一.什么是回文字 给定一个字符串,从前往后读和从后往前读,字符串序列不变.例如,河北省农村信用社的客服电话是“96369”,无论从后往前读,还是从前后往后读,各个字符出现的位置不变. 二.功能实现 ( ...
- 算法模板——splay区间反转 2
实现功能:同splay区间反转 1(基于BZOJ3223 文艺平衡树) 这次改用了一个全新的模板(HansBug:琢磨了我大半天啊有木有),大大简化了程序,同时对于splay的功能也有所完善 这里面没 ...
随机推荐
- How to install Eclipse in linux
http://askubuntu.com/questions/26632/how-to-install-eclipse
- 将回车键转换为Tab键
实现效果: 知识运用: KeyEventArgs类的KeyValue属性 public int KeyValue {get;} //获取KeyDown或KeyUp事件的键盘值 SendKeys类的Se ...
- 【转】Intellij Idea识别Java Web项目
使用maven生成一个Java项目,手动添加相应的web目录WEB_INF,web.xml等,此时idea没有自动识别为web项目,此时编辑web.xml文件会出现一些不该出现的错误,需要做的就是让i ...
- PAT (Basic Level) Practise (中文)-1033. 旧键盘打字(20)
PAT (Basic Level) Practise (中文)-1033. 旧键盘打字(20) http://www.patest.cn/contests/pat-b-practise/1033 旧 ...
- 升级nodejs 与短小的n模块
要用指令升级nodejs到新版本要先安装n模块 window用不了n模块 可以用 nvm-windows : https://github.com/coreybutler/nvm-windows n ...
- OJ 大整数减法
描述 求两个大的正整数相减的差. 输入 共2行,第1行是被减数a,第2行是减数b(a > b).每个大整数不超过200位,不会有多余的前导零. 输出 一行,即所求的差. 样例输入 9999999 ...
- 004 html常用标签
html常用标签 1.无语义标签 <div></div> <span></span> 2.常用语义标签 <hn></hn> 标题 ...
- (10)zabbix item key详解
1. 灵活的参数 参数位置可用接收任意参数则是灵活的.例如vfs.fs.size[*],”*”星号可以使用任意的参数,例如:vfs.fs.size[/]vfs.fs.size[/opt] 2. Key ...
- (1) zabbix进程构成
进程介绍 zabbix_agentd客户端守护进程,此进程收集客户端数据,例如cpu负载.内存.硬盘使用情况等 zabbix_getzabbix工具,单独使用的命令,通常在server或者proxy端 ...
- PHP中文件锁与进程锁的使用区别
php中文网的一篇文章,收为己用了.源地址: http://www.php.cn/php-weizijiaocheng-376853.html 本篇文章主要介绍了PHP 文件锁与进程锁的使用示例,小编 ...