[模板]平衡树splay
气死我了,调了一个下午+两节课,各种大大小小的错误,各种调QAQ,最后总之是调出来了.
其实就是一个双旋操作,然后其他就是左儿子<当前节点<右儿子,剩下就是细节了.
题干:
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
插入xxx数
删除xxx数(若有多个相同的数,因只删除一个)
查询xxx数的排名(排名定义为比当前数小的数的个数+++。若有多个相同的数,因输出最小的排名)
查询排名为xxx的数
求xxx的前驱(前驱定义为小于xxx,且最大的数)
求xxx的后继(后继定义为大于xxx,且最小的数)
输入输出格式
输入格式:
第一行为nnn,表示操作的个数,下面nnn行每行有两个数optoptopt和xxx,optoptopt表示操作的序号( ≤opt≤ \leq opt \leq ≤opt≤ )
输出格式:
对于操作3,,,,,,,,,6每行输出一个数,表示对应答案
输入输出样例
输入样例#: 复制
输出样例#: 复制
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
#define pr pair<int,int>
#define mp make_pair
const int INF = ;
const double eps = 1e-;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
struct node
{
int v,fa,ch[],sum,recy;
}e[];
int n,points,N;
#define root e[0].ch[1]
void update(int x)
{
e[x].sum = e[e[x].ch[]].sum + e[e[x].ch[]].sum + e[x].recy;
}
int iden(int x)
{
return e[e[x].fa].ch[] == x ? : ;
}
void connect(int x,int f,int son)
{
e[x].fa = f;
e[f].ch[son] = x;
}
void rotate(int x)
{
int y = e[x].fa;
int mroot = e[y].fa;
int mrootson = iden(y);
int yson = iden(x);
int b = e[x].ch[yson ^ ];
connect(b,y,yson);
connect(y,x,yson ^ );
connect(x,mroot,mrootson);
update(y);
update(x);
}
void splay(int at,int to)
{
to = e[to].fa;
while(e[at].fa != to)
{
int up = e[at].fa;
if(e[up].fa == to) rotate(at);
else if(iden(up) == iden(at))
{
rotate(up);
rotate(at);
}
else
{
rotate(at);
rotate(at);
}
}
}
int crepoint(int v,int fa)
{
n++;
e[n].v = v;
e[n].fa = fa;
// cout<<v<<" "<<fa<<endl;
e[n].sum = e[n].recy = ;
return n;
}
void destroy(int x)
{
e[x].v = e[x].ch[] = e[x].ch[] = e[x].sum = e[x].fa = e[x].recy = ;
if(x == n)
n--;
while(e[n].v == && e[n].sum == && n > )
n--;
}
int find(int v)
{
int now = root;
while(true)
{
if(e[now].v == v)
{
splay(now,root);
return now;
}
int nxt = v < e[now].v ? : ;
if(!e[now].ch[nxt]) return ;
now = e[now].ch[nxt];
}
}
int build(int v)
{
points++;
// cout<<v<<endl;
if(n == )
{
root = ;
crepoint(v,);
}
else
{
int now = root;
while(true)
{
// cout<<now<<endl;
e[now].sum++;
if(v == e[now].v)
{
e[now].recy++;
return now;
}
int nxt = v < e[now].v ? : ;
if(!e[now].ch[nxt])
{
crepoint(v,now);
e[now].ch[nxt] = n;
return n;
}
now = e[now].ch[nxt];
}
}
return ;
}
void push(int v)
{
int add = build(v);
if( rand() % == )
splay(add,root);
}
void pop(int v)
{
int deal = find(v);
if(!deal) return;
points--;
if(e[deal].recy > )
{
e[deal].recy--;
e[deal].sum--;
return;
}
if(!e[deal].ch[])
{
root = e[deal].ch[];
e[root].fa = ;
}
else
{
int lef = e[deal].ch[];
while(e[lef].ch[]) lef = e[lef].ch[];
splay(lef,e[deal].ch[]);
int rig = e[deal].ch[];
connect(rig,lef,);connect(lef,,);
update(lef);
}
destroy(deal);
}
int Rank(int v)
{
int ans = ,now = root;
// cout<<v<<endl;
while(true)
{
if(e[now].v == v)
return ans + e[e[now].ch[]].sum + ;
if(now == ) return ;
if(v < e[now].v) now = e[now].ch[];
else
{
ans = ans + e[e[now].ch[]].sum + e[now].recy;
now = e[now].ch[];
}
}
//if(now) splay(now,root);
return ;
}
int atRank(int x)
{
if(x > points) return -INF;
int now = root;
// cout<<root<<endl;
while(true)
{
// cout<<now<<endl;
int minused = e[now].sum - e[e[now].ch[]].sum;
if(x > e[e[now].ch[]].sum && x <= minused) break;
if(x < minused) now = e[now].ch[];
else
{
x = x - minused;
now = e[now].ch[];
}
}
//splay(now,root);
return e[now].v;
}
int upper(int v)
{
int now = root;
int result = INF;
while(now)
{
if(e[now].v > v && e[now].v < result) result = e[now].v;
if(v < e[now].v) now = e[now].ch[];
else
now = e[now].ch[];
}
return result;
}
int lower(int v)
{
int now = root;
int result = -INF;
while(now)
{
// cout<<now<<endl;
if(e[now].v < v && e[now].v > result)
result = e[now].v;
if(v > e[now].v) now = e[now].ch[];
else
now = e[now].ch[];
}
return result;
}
void Szcheck( int pos ){
if( e[pos].ch[] ) Szcheck(e[pos].ch[]);
if( e[pos].ch[] ) Szcheck(e[pos].ch[]);
if( e[e[pos].ch[]].sum + + e[e[pos].ch[]].sum != e[pos].sum ){
cout << "Size Error At Pos" << pos << endl;
}
}
void gg()
{
cout<<n<<endl;
duke(i,,n)
{
printf("%d ",e[i].v);
}
puts("");
}
int main()
{
// freopen("3369.in","r",stdin);
read(N);
duke(i,,N)
{
int opt,value;
// cout<<endl<<i<<endl;
read(opt);read(value);
// if(opt != 1 && opt != 2)
// cout<<opt<<" "<<value<<endl;
switch(opt)
{
case : push(value);break;
case : pop(value);break;
case : cout<<Rank(value)<<endl;break;
case : {cout<<atRank(value)<<endl;}break;
case : cout<<lower(value)<<endl;break;
case : cout<<upper(value)<<endl;break;
case : gg();
}
//Szcheck(root);
// cout<<i<<endl;
}
return ;
}
/*
10
1 106465
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
4 1
*/
代码有点长...
[模板]平衡树splay的更多相关文章
- [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- 平衡树模板【splay的实现】
[平衡树splay实现] 无注释代码 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=1e ...
- 【BZOJ3224】Tyvj 1728 普通平衡树 Splay
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
- BZOJ3224/洛谷P3391 - 普通平衡树(Splay)
BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...
- 平衡树——splay 一
splay 一种平衡树,同时也是二叉排序树,与treap不同,它不需要维护堆的性质,它由Daniel Sleator和Robert Tarjan(没错,tarjan,又是他)创造,伸展树是一种自调整二 ...
- hiho #1329 : 平衡树·Splay
#1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...
- Hihocoder 1329 平衡树·Splay(平衡树)
Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...
随机推荐
- svn无法显示日期和作者
当遇到这种情况,只要把这个read改为none就可以显示了 亲测绝对管用
- 洛谷——P3807 【模板】卢卡斯定理
P3807 [模板]卢卡斯定理 洛谷智推模板题,qwq,还是太弱啦,组合数基础模板题还没做过... 给定n,m,p($1\le n,m,p\le 10^5$) 求 $C_{n+m}^{m}\ mod\ ...
- JDBC在Java Web中的应用
JDBC在Java Web中的应用 制作人:全心全意 在Java Web开发中,JDBC的应用十分广泛.通常情况下,Web程序操作数据库都是通过JDBC实现,即使目前数据库方面的开源框架层出不穷,但其 ...
- 腾讯云,体验域名注册解析与SSL证书
体验域名注册解析与SSL证书 购买域名 任务时间:30min ~ 60min 在腾讯云上购买域名 首先需要在腾讯云上购买域名, 点击以下链接可以观看购买操作的指引 如何在腾讯云上购买域名 域名解析 域 ...
- BZOJ 1468 Tree 【模板】树上点分治
#include<cstdio> #include<algorithm> #define N 50010 #define M 500010 #define rg registe ...
- MySQL 分库、分表
Mysql Sharding 前言 1)Sharding是按照一定规则重新分布数据的方式 2)解决单机写入压力过大和容量问题 3) 解决单机查询慢的问题 4)本文主要根据用户登录场景分析 Shard ...
- 调试LM1117电压转换芯片
LM1117(不是LM117)电源芯片是低压差线性稳压器,简称LDO(low dropout regulator),是一种非隔离(输入输出电压的地是一个地)的电压转换芯片.因此,在使用的时候,尽量让输 ...
- 类中的__call__()
class A: def __call__(self, *args, **kwargs): print('执行了call方法') def call(self): print('执行call方法') c ...
- IDEA建立一个可运行的struts2项目
参考博客:https://blog.csdn.net/shuai_wy/article/details/79027573 直接使用IDEA创建struts2项目,配置好tomcat后是跑不起来的 需要 ...
- 泛型转换https://www.cnblogs.com/eason-chan/p/3633210.html
import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;//总结1.st.getClass==Student. ...