splay 模板 洛谷3369
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
插入 xx 数
删除 xx 数(若有多个相同的数,因只删除一个)
查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 。若有多个相同的数,因输出最小的排名)
查询排名为 xx 的数
求 xx 的前驱(前驱定义为小于 xx ,且最大的数)
求 xx 的后继(后继定义为大于 xx ,且最小的数)
输入输出格式
输入格式:
第一行为 nn ,表示操作的个数,下面 nn 行每行有两个数 optopt 和 xx , optopt 表示操作的序号( 1 \leq opt \leq 6 1≤opt≤6 )
输出格式:
对于操作 3,4,5,63,4,5,6 每行输出一个数,表示对应答案
输入输出样例
输入样例#1: 复制
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
输出样例#1: 复制
106465
84185
492737
说明
时空限制:1000ms,128M
1.n的数据范围: n \leq 100000 n≤100000
2.每个数的数据范围: [-{10}^7, {10}^7][−10
7
,10
7
]
来源:Tyvj1728 原名:普通平衡树
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100005;
const int inf = 0x7f7f7f7f;
struct Node{
int v,fa;
int ch[2];
int sum;
int recy;
}node[MAXN];
int n,cnt,points;
inline void update(int x){
node[x].sum=node[node[x].ch[1]].sum+node[node[x].ch[0]].sum+node[x].recy;
}
inline bool jud(int x){
return node[node[x].fa].ch[0]==x?0:1;
}
inline void connect(int x,int f,int son){
node[x].fa=f;
node[f].ch[son]=x;
}
inline void rotate(int x){
int y=node[x].fa;
int mroot=node[y].fa;
int mrootson=jud(y);
int yson=jud(x);
int oth=node[x].ch[yson^1];
connect(oth,y,yson);
connect(y,x,(yson^1));
connect(x,mroot,mrootson);
update(y);update(x);
}
inline void splay(int at,int to){
to=node[to].fa;
while(node[at].fa!=to){
int up=node[at].fa;
if(node[up].fa==to) rotate(at);
else if(jud(up)==jud(at)){
rotate(up);
rotate(at);
}
else{
rotate(at);
rotate(at);
}
}
}
inline int crepoint(int x,int f){
node[++cnt].v=x;
node[cnt].fa=f;
node[cnt].sum=1;
node[cnt].recy=1;
return cnt;
}
inline void destroy(int x){
node[x].v=node[x].fa=node[x].sum=node[x].recy=node[x].ch[0]=node[x].ch[1]=0;
if(x==cnt) cnt--;
}
inline int find(int v){
int now=node[0].ch[1];
while(1){
if(node[now].v==v){
splay(now,node[0].ch[1]);
return now;
}
int nxt=v<node[now].v?0:1;
if(!node[now].ch[nxt]) return 0;
now=node[now].ch[nxt];
}
}
inline int build(int x){
points++;
if(cnt==0){
node[0].ch[1]=1;
crepoint(x,0);
}
else{
int now=node[0].ch[1];
while(1){
node[now].sum++;
if(x==node[now].v){
node[now].recy++;
return now;
}
int nxt=x<node[now].v?0:1;
if(!node[now].ch[nxt]){
crepoint(x,now);
node[now].ch[nxt]=cnt;
return cnt;
}
now=node[now].ch[nxt];
}
}
return 0;
}
inline void push(int x){
int add=build(x);
splay(add,node[0].ch[1]);
}
inline void pop(int v){
int deal=find(v);
if(!deal) return;
points--;
if(node[deal].recy>1){
node[deal].recy--;
node[deal].sum--;
return;
}
if(!node[deal].ch[0]){
node[0].ch[1]=node[deal].ch[1];
node[node[0].ch[1]].fa=0;
}
else{
int lef=node[deal].ch[0];
while(node[lef].ch[1]) lef=node[lef].ch[1];
splay(lef,node[deal].ch[0]);
int rig=node[deal].ch[1];
connect(rig,lef,1);connect(lef,0,1);
update(lef);
}
destroy(deal);
}
int rank(int x){
int ans=0;
int now=node[0].ch[1];
while(1){
if(node[now].v==x) return ans+node[node[now].ch[0]].sum+1;
if(now==0) return 0;
if(x<node[now].v) now=node[now].ch[0];
else{
ans+=node[node[now].ch[0]].sum+node[now].recy;
now=node[now].ch[1];
}
}
if(now) splay(now,node[0].ch[1]);
return 0;
}
int atrank(int x){
if(x>points) return -inf;
int now=node[0].ch[1];
while(1){
int minn=node[now].sum-node[node[now].ch[1]].sum;
if(x>node[node[now].ch[0]].sum && x<=minn) break;
if(x<minn) now=node[now].ch[0];
else{
x=x-minn;
now=node[now].ch[1];
}
}
splay(now,node[0].ch[1]);
return node[now].v;
}
inline int lower(int x){
int now=node[0].ch[1];
int res=-inf;
while(now){
if(node[now].v<x && node[now].v>res) res=node[now].v;
if(x>node[now].v) now=node[now].ch[1];
else now=node[now].ch[0];
}
return res;
}
inline int upper(int x){
int now=node[0].ch[1];
int res=inf;
while(now){
if(node[now].v>x && node[now].v<res) res=node[now].v;
if(x<node[now].v) now=node[now].ch[0];
else now=node[now].ch[1];
}
return res;
}
int main(){
scanf("%d",&n);
push(inf);push(-inf);
for(register int i=1;i<=n;i++){
int opt,x;
scanf("%d%d",&opt,&x);
if(opt==1) push(x);
else if(opt==2) pop(x);
else if(opt==3) printf("%d\n",rank(x)-1);
else if(opt==4) printf("%d\n",atrank(x+1));
else if(opt==5) printf("%d\n",lower(x));
else printf("%d\n",upper(x));
}
return 0;
}
splay 模板 洛谷3369的更多相关文章
- 【数论】卢卡斯定理模板 洛谷P3807
[数论]卢卡斯定理模板 洛谷P3807 >>>>题目 [题目] https://www.luogu.org/problemnew/show/P3807 [输入格式] 第一行一个 ...
- KMP字符串匹配 模板 洛谷 P3375
KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...
- 在洛谷3369 Treap模板题 中发现的Splay详解
本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原 ...
- BZOJ3224 洛谷3369 Tyvj 1728 普通平衡树 splay
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3224 题意概括 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. ...
- 【模板】LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]
以题写模板. 写了两个:n^2版本与nlogn版本 P1091 合唱队形 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队 ...
- 树链剖分模板(洛谷P3384)
洛谷P3384 #include <bits/stdc++.h> #define DBG(x) cerr << #x << " = " < ...
- (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
- 洛谷.3369.[模板]普通平衡树(Splay)
题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...
- 【Splay】洛谷3372 【模板】线段树 1
Splay区间加,询问区间和. #include<cstdio> #include<iostream> #include<cstring> #include< ...
随机推荐
- 分块——cf1207F
这么傻逼的题当时想了那么久 用a数组维护原序列,b[i][j]表示 pos%i=j 的 a[pos]之和 对于每个修改1 x y,先直接修改a[x],然后枚举i=1..700,修改b[i][x%i] ...
- TrMemo控件
unit TrMemo; {$R-} interface uses Windows, Messages, Controls, StdCtrls, Classes; const TMWM__Specia ...
- docker哪些平台技术(3)
容器平台技术 容器核心技术使得容器能够在单个 host 上运行.而容器平台技术能够让容器作为集群在分布式环境中运行. 容器平台技术包括容器编排引擎.容器管理平台和基于容器的 PaaS. 容器编排引擎 ...
- JAVA并发工具类---------------(CountDownLatch和CyclicBarrier)
CountDownLatch是什么 CountDownLatch,英文翻译为倒计时锁存器,是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 闭锁可以延迟线程的进 ...
- spring aop的前奏,动态代理 (5)
目录 一.先看一个计算器的抽取和实现 二.使用动态代理解决以上问题. 1 设计原理 2 代码实现 2.1 接口代码 2.2 实现接口的代码 2.3 测试代码 2.3 创建动态代理类 2.4 动态代理类 ...
- Java-Class-FC:java.time.Duration
ylbtech-Java-Class-FC:java.time.Duration 1.返回顶部 2.返回顶部 3.返回顶部 1. /* * Copyright (c) 2012, 2015, ...
- project的操作说明
project 1 操作的步骤 设定一个起始时间:7月1号 安排好摘要(任务)的先后顺序 一个一个任务的来:A任务,下面有几个分布实现的部门: 设计部门 3个工作日 程序部门 1个工作日.然后配置相互 ...
- linux jps命令
原文链接: http://www.cnblogs.com/qlqwjy/p/7928410.html https://blog.csdn.net/u013250071/article/details/ ...
- gcc将c源文件中的宏展开
1: sudo gcc -P -I. -I../instrument/stubs -I../instrument/stubs -I../ -E ctrl_xfer32.cc -o preprocess ...
- leetcode.字符串.12整数转罗马数字-Java
1. 具体题目 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 ...