#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1000000
#define INF 2147483647
int n,fa[maxn],val[maxn],c[maxn][2],root,tot,siz[maxn],cnt[maxn];
void Maintain(int x)
{
siz[x]=siz[c[x][0]]+siz[c[x][1]]+cnt[x];
}
void NewNode(int &x,int Fa,int key)
{
x=++tot;
fa[x]=Fa;
c[x][0]=c[x][1]=0;
val[x]=key;
siz[x]=cnt[x]=1;
}
void Rotate(int x,bool flag)
{
int y=fa[x];
c[y][!flag]=c[x][flag];
fa[c[x][flag]]=y;
if(fa[y]){
c[fa[y]][c[fa[y]][1]==y]=x;
}
fa[x]=fa[y];
c[x][flag]=y;
fa[y]=x;
Maintain(y);
Maintain(x);
}
void Splay(int x,int goal)
{
if(!x){
return;
}
int y;
while((y=fa[x])!=goal){
if(fa[y]==goal){
Rotate(x,c[y][0]==x);
}
else{
if((c[y][0]==x)==(c[fa[y]][0]==y)){
Rotate(y,c[fa[y]][0]==y);
}
else{
Rotate(x,c[y][0]==x);
y=fa[x];
}
Rotate(x,c[y][0]==x);
}
}
Maintain(x);
if(!goal){
root=x;
}
}
int Find(int key,int x=root)
{
while(c[x][val[x]<key]){
if(val[x]==key){
return x;
}
x=c[x][val[x]<key];
}
return x;
}
void Insert(int key)
{
if(!root){
NewNode(root,0,key);
return;
}
int x=Find(key);
if(val[x]==key){
++cnt[x];
Splay(x,0);
return;
}
NewNode(c[x][val[x]<key],x,key);
Splay(c[x][val[x]<key],0);
}
int Findmax(int x=root)
{
while(c[x][1]){
x=c[x][1];
}
return x;
}
int Findmin(int x=root)
{
while(c[x][0]){
x=c[x][0];
}
return x;
}
void Delete(int key)
{
int x=Find(key);
Splay(x,0);
if(val[x]==key){
--cnt[x];
if(!cnt[x]){
if(!c[x][0]&&!c[x][1]){
root=0;
}
else if(!c[x][0]||!c[x][1]){
fa[c[x][c[x][0]==0]]=0;
root=c[x][c[x][0]==0];
}
else{
int y=Findmax(c[x][0]);
Splay(y,root);
c[y][1]=c[root][1];
fa[c[root][1]]=y;
root=y;
fa[root]=0;
Maintain(root);
}
}
else{
Maintain(x);
}
}
}
int Rank(int key)
{
int x=Find(key);
Splay(x,0);
return siz[c[x][0]]+1;
}
int Kth(int K,int x=root)
{
while(1){
int Siz0=siz[c[x][0]];
if(K<=Siz0){
x=c[x][0];
}
else if(K<=Siz0+cnt[x]){
return val[x];
}
else{
K-=(Siz0+cnt[x]);
x=c[x][1];
}
}
}
int GetPre(int key)
{
int x=Find(key);
if(val[x]==key){
Splay(x,0);
return val[Findmax(c[x][0])];
}
while(val[x]>key&&fa[x]){
x=fa[x];
}
return val[x];
}
int GetNex(int key)
{
int x=Find(key);
if(val[x]==key){
Splay(x,0);
return val[Findmin(c[x][1])];
}
while(val[x]<key&&fa[x]){
x=fa[x];
}
return val[x];
}
int main(){
int op, x;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&op,&x);
if(op==1){
Insert(x);
}
else if(op==2){
Delete(x);
}
else if(op==3){
printf("%d\n",Rank(x));
}
else if(op==4){
printf("%d\n",Kth(x));
}
else if(op==5){
printf("%d\n",GetPre(x));
}
else{
printf("%d\n",GetNex(x));
}
}
return 0;
}

【Splay】bzoj3224 Tyvj 1728 普通平衡树的更多相关文章

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

    bzoj3224: Tyvj 1728 普通平衡树(平衡树) 总结 a. cout<<(x=3)<<endl;这句话输出的值是3,那么对应的,在splay操作中,当父亲不为0的 ...

  2. [BZOJ3224]Tyvj 1728 普通平衡树

    [BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...

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

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

  4. bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5354  Solved: 2196[Submit][Sta ...

  5. 绝对是全网最好的Splay 入门详解——洛谷P3369&BZOJ3224: Tyvj 1728 普通平衡树 包教包会

    平衡树是什么东西想必我就不用说太多了吧. 百度百科: 一个月之前的某天晚上,yuli巨佬为我们初步讲解了Splay,当时接触到了平衡树里的旋转等各种骚操作,感觉非常厉害.而第二天我调Splay的模板竟 ...

  6. bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)

    (其实今天好热啊? 题目大意:插入,删除,k小,前驱后继,数的排名. splay和treap裸题...过几天补个treap的 splay: #include<iostream> #incl ...

  7. [bzoj3224]Tyvj 1728 普通平衡树——splay模板

    题目 你需要写一种数据结构支援以下操作. 插入元素. 删除元素. 查询元素的排名. 查询第k小的元素. 查询元素前趋. 查询元素后继. 题解 BBST裸题. 代码 #include <cstdi ...

  8. 【权值分块】bzoj3224 Tyvj 1728 普通平衡树

    权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 按值域删除元素 O(1) O(1) O(sqrt(n ...

  9. 【权值线段树】bzoj3224 Tyvj 1728 普通平衡树

    一个板子. #include<cstdio> #include<algorithm> using namespace std; #define N 100001 struct ...

随机推荐

  1. HDU 1728 逃离迷宫 (广搜)

    题目链接 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可 ...

  2. bzoj 2669 状压DP

    因为最多有8个'X',所以我们可以用w[i][s]来表示现在我们填了前i个数,填的X的为S,因为每次新加进来的数都不影响前面的最小值,所以我们可以随便添加,这样就有了剩下所有位置的方案,每次都这样转移 ...

  3. 6.0docker Dockerfile文件

    指令格式 #注释 FROM :基础镜像 MAINTAINER:镜像的作者信息 RUN :指定(构建过程中)当前镜像中运行的命令 EXPOSE :指定运行镜像的容器应用程序所使用的端口 容器但不会打开, ...

  4. C++转换构造函数和隐式转换函数 ~ 转载

    原文地址: C++转换构造函数和隐式转换函数 用转换构造函数可以将一个指定类型的数据转换为类的对象.但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Complex类对象转换成doubl ...

  5. gpio子系统和pinctrl子系统(下)

    情景分析 打算从两个角度来情景分析,先从bsp驱动工程师的角度,然后是驱动工程师的角度,下面以三星s3c6410 Pinctrl-samsung.c为例看看pinctrl输入参数的初始化过程(最开始的 ...

  6. device tree --- label

    [label:] <device node name>[@ unit-address] 為 device node 取 label name, 可以在其它位置使用 &label 存 ...

  7. python实战===用python调用jar包(原创)

    一个困扰我很久的问题,今天终于解决了.用python调用jar包 很简单,但是网上的人就是乱转载.自己试都不试就转载,让我走了很多弯路 背景:python3.6 32位   + jre 32位  +  ...

  8. <摘录>Fedora添加国内源和本地源

    <摘录>Fedora添加国内源和本地源 http://www.cnblogs.com/hummersofdie/p/3915070.html fedora的软件源信息文件(*.repo)都 ...

  9. [hadoop][基本原理]zookeeper简单使用

    代码:https://github.com/xufeng79x/ZkClientTest 1.简介 zookeeper的基本原理和使用场景描述可参考:[hadoop][基本原理]zookeeper基本 ...

  10. 如何设置static tableview的section区域高度

    重写代理方法- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { i ...