洛谷P3835 【模板】可持久化平衡树
题目背景
本题为题目 普通平衡树 的可持久化加强版。
数据已经经过强化
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本):
- 插入x数
- 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作)
- 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
- 查询排名为x的数
- 求x的前驱(前驱定义为小于x,且最大的数,如不存在输出-2147483647)
- 求x的后继(后继定义为大于x,且最小的数,如不存在输出2147483647)
和原本平衡树不同的一点是,每一次的任何操作都是基于某一个历史版本,同时生成一个新的版本。(操作3, 4, 5, 6即保持原版本无变化)
每个版本的编号即为操作的序号(版本0即为初始状态,空树)
输入输出格式
输入格式:
第一行包含一个正整数N,表示操作的总数。
接下来每行包含三个正整数,第 ii 行记为 v_i, opt_i, x_ivi,opti,xi。
v_ivi表示基于的过去版本号( 0 leq v_i < i0≤vi<i ),opt_iopti 表示操作的序号( 1 leq opt leq 61≤opt≤6 ), x_ixi 表示参与操作的数值
输出格式:
每行包含一个正整数,依次为各个3,4,5,6操作所对应的答案
输入输出样例
输入样例#1:
10
0 1 9
1 1 3
1 1 10
2 4 2
3 3 9
3 1 2
6 4 1
6 2 9
8 6 3
4 5 8
输出样例#1:
9
1
2
10
3
说明
数据范围:
对于10%的数据满足: 1 leq n leq 101≤n≤10
对于30%的数据满足: 1 leq n leq 2cdot {10}^21≤n≤2⋅102
对于50%的数据满足: 1 leq n leq 3cdot {10}^31≤n≤3⋅103
对于80%的数据满足: 1 leq n leq {10}^51≤n≤105
对于90%的数据满足: 1 leq n leq 2cdot {10}^51≤n≤2⋅105
对于100%的数据满足: 1 leq n leq 5cdot {10}^51≤n≤5⋅105 , -{10}^9 leq x_i leq {10}^9−109≤xi≤109
经实测,正常常数的可持久化平衡树均可通过,请各位放心
样例说明:
共10次操作,11个版本,各版本的状况依次是:
- [][]
- [9][9]
- [3, 9][3,9]
- [9, 10][9,10]
- [3, 9][3,9]
- [9, 10][9,10]
- [2, 9, 10][2,9,10]
- [2, 9, 10][2,9,10]
- [2, 10][2,10]
- [2, 10][2,10]
- [3, 9][3,9]
也是没谁了
数据压根就没有5.6的21***的情况
而且不知道为啥我的样例没过就A了。。
#include<bits/stdc++.h>
using namespace std;
#define ls tree[k].ch[0]
#define rs tree[k].ch[1]
const int MAXN=1e6+10,INF=1e7;
inline char nc()
{
static char buf[MAXN],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
char c=nc();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
return x*f;
}
struct node
{
int pri,v,ch[2],siz;
}tree[MAXN];
int x,y,z,tot=0,root[MAXN];
int new_node(int val)
{
tree[++tot].pri=rand()*rand(),tree[tot].v=val,tree[tot].siz=1;
return tot;
}
void update(int k){ tree[k].siz=tree[ls].siz+tree[rs].siz+1; }
void split(int now,int k,int &x,int &y)
{
if(!now) {x=y=0;return ;}
if(tree[now].v<=k) x=now,split(tree[now].ch[1],k,tree[now].ch[1],y);
else y=now,split(tree[now].ch[0],k,x,tree[now].ch[0]);
update(now);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(tree[x].pri<tree[y].pri) {tree[x].ch[1]=merge(tree[x].ch[1],y),update(x);return x;}
else {tree[y].ch[0]=merge(x,tree[y].ch[0]),update(y);return y;}
}
int kth(int k,int x)// 查询排名
{
if(x<=tree[ls].siz) return kth(ls,x);
else if(x==tree[ls].siz+1) return k;
else return kth(rs,x-tree[ls].siz-1);
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
srand((unsigned)time(NULL));
int n=read();
for(int i=1;i<=n;i++)
{
int pre=read(),how=read(),a=read();
root[i]=root[pre];
if(how==1) split(root[i],a,x,y),root[i]=merge(merge(x,new_node(a)),y);
else if(how==2) split(root[i],a,x,z),split(x,a-1,x,y),y=merge(tree[y].ch[0],tree[y].ch[1]),root[i]=merge(merge(x,y),z);
else if(how==3) split(root[i],a-1,x,y),printf("%dn",tree[x].siz+1),root[i]=merge(x,y);
else if(how==4) printf("%dn",tree[kth(root[i],a)].v);
else if(how==5) split(root[i],a-1,x,y),printf("%dn",tree[kth(x,tree[x].siz)].v),root[i]=merge(x,y);
else if(how==6) split(root[i],a,x,y),printf("%dn",tree[kth(y,1)].v),root[i]=merge(x,y);
}
return 0;
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 操作系统实验多线程编程中的读者优先和写者优先
- 【python】使用csv库以字典格式读写csv文件
- 基于TypeScript封装Axios笔记(八)
- springmvc之HttpMessageConverter<T>
- django-模板之静态文件加载(十四)
- springmvc之使用JstlView
- django-模板之include标签(十五)
- 【pytorch】改造mobilenet_v2进行multi-class classification(多标签分类)
- 走进STL - heap,小树芽
- 走进STL - 序列式容器(常用篇)
- springmvc之RequestMapping中的请求方式
- 拥抱STL - union,天作之秀
- 拥抱STL -typename该怎么理解
- 走近STL - map,只愿一键对一值
- springmvc之使用servlet原生API作为参数