洛谷.3369.[模板]普通平衡树(Splay)
题目链接
第一次写(2017.11.7):
#include<cstdio>
#include<cctype>
using namespace std;
const int N=1e5+5,INF=1e9;
int size,root,t[N],sz[N],son[N][2],fa[N],cnt[N];
inline int read()
{
int now=0,f=1;register char c=getchar();
for(;!isdigit(c);c=getchar())
if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=getchar());
return now*f;
}
inline void Update(int rt)
{
sz[rt]= sz[son[rt][0]]+sz[son[rt][1]]+cnt[rt];
}
void Rotate(int x,int &k)
{
int a=fa[x],b=fa[a],l=(son[a][1]==x),r=l^1;
if(a==k) k=x;
else son[b][son[b][1]==a]=x;
fa[a]=x, fa[x]=b, fa[son[x][r]]=a,
son[a][l]=son[x][r], son[x][r]=a;
Update(a),Update(x);
}
void Splay(int x,int &rt)
{
int a,b;
while(x!=rt)
{
a=fa[x], b=fa[a];
if(a!=rt)
{
if((son[a][0]==x)^(son[b][0]==a)) Rotate(x,rt);
else Rotate(a,rt);
}
Rotate(x,rt);
}
}
void Insert(int k,int v)
{
int f=0;
while(k && t[k]!=v) f=k, k=son[k][v>t[k]];
if(k) ++cnt[k];
else
{
k=++size, sz[k]=cnt[k]=1, fa[k]=f, t[k]=v;
if(f) son[f][v>t[f]]=k;
}
Splay(k,root);
}
void Get_Rank(int k,int v)
{
if(!k) return;
while(son[k][v>t[k]] && t[k]!=v) k=son[k][v>t[k]];
Splay(k,root);
}
int Rank(int k,int x)
{
// ++x;//加了哨兵元素
//if(sz[k]<x) return 0;
while(1)
{
if(sz[son[k][0]]<x && sz[son[k][0]]+cnt[k]>=x) return k;
if(sz[son[k][0]]<x) x-=sz[son[k][0]]+cnt[k],k=son[k][1];
else k=son[k][0];
}
}
int Find(int v,int f)
{
Get_Rank(root,v);
if((t[root]>v && f)||(t[root]<v && !f)) return root;
int k=son[root][f];f^=1;
while(son[k][f]) k=son[k][f];
return k;
}
void Delete(int k,int v)
{
Get_Rank(root,v);
if(cnt[root]>1){--cnt[root],--sz[root];return;}
int x=root;
if(son[root][0] && son[root][1])
{
int k=son[root][1];root=k;
while(son[k][0]) k=son[k][0];
sz[k]+=sz[son[x][0]], fa[son[x][0]]=k, son[k][0]=son[x][0];
Splay(k,root);
}
else
root=son[root][0]+son[root][1];
fa[root]=0;
}
int main()
{
// freopen("testdata.in","r",stdin);
int n=read(),opt,x;
// Insert(root,-INF),Insert(root,INF);
while(n--)
{
opt=read(),x=read();
if(opt==1) Insert(root,x);
else if(opt==2) Delete(root,x);
else if(opt==3) Get_Rank(root,x), printf("%d\n",sz[son[root][0]]+1);
else if(opt==4) printf("%d\n",t[Rank(root,x)]);
else if(opt==5) printf("%d\n",t[Find(x,0)]);
else printf("%d\n",t[Find(x,1)]);
}
return 0;
}
第二次写(2017.12.3):
#include<cstdio>
#include<cctype>
const int N=1e5+5;
int n,root,size,sz[N],cnt[N],t[N],son[N][2],fa[N];
inline int read()
{
int now=0,f=1;register char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=getchar());
return now*f;
}
inline void Update(int rt)
{
sz[rt]=sz[son[rt][0]]+sz[son[rt][1]]+cnt[rt];
}
void Rotate(int x,int &k)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(a==k) k=x;
else son[b][son[b][1]==a]=x;
fa[x]=b, fa[a]=x, fa[son[x][r]]=a;
son[a][l]=son[x][r], son[x][r]=a;
Update(a),Update(x);
}
void Splay(int x,int &k)
{
while(x!=k)
{
int a=fa[x],b=fa[a];
if(a!=k)
{
if((son[a][0]==x)^(son[b][0]==a)) Rotate(x,k);
else Rotate(a,k);
}
Rotate(x,k);
}
}
void Insert(int v,int k)
{
int f=0;
while(k && t[k]!=v) f=k,k=son[k][v>t[k]];//v>t[k]!
if(k) ++cnt[k];
else
{
k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f;
if(f) son[f][v>t[f]]=k;
}
Splay(k,root);
}
void Rank(int v,int k)
{
if(!k) return;//!
while(son[k][v>t[k]] && t[k]!=v) k=son[k][v>t[k]];
Splay(k,root);
}
void Delete(int v)
{
Rank(v,root);//!
// while(son[k][v>t[k]] && t[k]!=v) k=son[k][v>t[k]];//!
if(cnt[root]>1) {--cnt[root],--sz[root]; return;}//--sz[k]!
if(son[root][0] && son[root][1])//两种情况!
{
int tmp=root,k=son[root][1];
root=k;//root=k!
while(son[k][0]) k=son[k][0];
sz[k]+=sz[son[tmp][0]],//加sz!
fa[son[tmp][0]]=k, son[k][0]=son[tmp][0];
Splay(k,root);//!
}
else root=son[root][0]+son[root][1];
fa[root]=0;//!
// Splay(k,root);
}
int Get_Rank(int x,int k)
{
while(1)
{
if(sz[son[k][0]]<x && sz[son[k][0]]+cnt[k]>=x) return k;
if(sz[son[k][0]]<x) x-=sz[son[k][0]]+cnt[k],k=son[k][1];
else k=son[k][0];
}
}
int Find(int v,int f)
{
Rank(v,root);
if((t[root]>v && !f)||(t[root]<v && f)) return root;
int k=son[root][f^1];
while(son[k][f]) k=son[k][f];
return k;
}
int main()
{
// freopen("3369.in","r",stdin);
n=read();
int opt,x;
while(n--)
{
opt=read(),x=read();
if(opt==1) Insert(x,root);
else if(opt==2) Delete(x);
else if(opt==3) Rank(x,root),printf("%d\n",sz[son[root][0]]+1);
else if(opt==4) printf("%d\n",t[Get_Rank(x,root)]);
else if(opt==5) printf("%d\n",t[Find(x,1)]);
else printf("%d\n",t[Find(x,0)]);
}
return 0;
}
第三次写(2018.4.4):(码风变化有点大啊)
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define MAXIN 500000
const int N=2e5+5;
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
namespace Splay
{
#define lson son[x][0]
#define rson son[x][1]
int root,size,fa[N],son[N][2],sz[N],t[N],cnt[N];
inline void Update(int x){
sz[x]=sz[lson]+sz[rson]+cnt[x];
}
void Rotate(int x,int &k)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(k==a) k=x;
else son[b][son[b][1]==a]=x;
fa[a]=x, fa[x]=b, fa[son[x][r]]=a,
son[a][l]=son[x][r], son[x][r]=a;
Update(a);// Update(x);
}
void Splay(int x,int &k)
{
while(x!=k)
{
int a=fa[x],b=fa[a];
if(a!=k) (son[a][1]==x^son[b][1]==a)?Rotate(x,k):Rotate(a,k);
Rotate(x,k);
}
Update(x);
}
void Insert(int v,int k)
{
int f=0;
while(t[k]!=v&&k) f=k,k=son[k][v>t[k]];
if(k) ++cnt[k];
else{
k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f;
if(f) son[f][v>t[f]]=k;
}
Splay(k,root);
}
void Rank(int v,int k)
{
// if(!k) return;
while(t[k]!=v && son[k][v>t[k]]) k=son[k][v>t[k]];
Splay(k,root);
}
void Delete(int v,int k)
{
Rank(v,root);
if(cnt[root]>1) --cnt[root],--sz[root];
else if(son[root][0]&&son[root][1])
{
int ls=son[root][0],k=son[root][1];
fa[root=k]=0;
while(son[k][0]) k=son[k][0];
fa[ls]=k, son[k][0]=ls;// sz[k]+=sz[ls];
Splay(k,root);
}
else root=son[root][0]^son[root][1],fa[root]=0;
}
int Get_Rank(int k,int x)
{
while(1)
{
if(sz[lson]<k && sz[lson]+cnt[x]>=k) return x;
if(sz[lson]<k) k-=sz[lson]+cnt[x],x=rson;
else x=lson;
}
}
int Find(int v,int w)
{
Rank(v,root);
if((t[root]>v&&!w)||(t[root]<v&&w)) return root;//!
int x=son[root][w^1];
while(son[x][w]) x=son[x][w];
return x;
}
}
using namespace Splay;
int main()
{
int n=read(),opt;
while(n--)
switch(opt=read())
{
case 1: Insert(read(),root); break;
case 2: Delete(read(),root); break;
case 3: Rank(read(),root),printf("%d\n",sz[son[root][0]]+1); break;
case 4: printf("%d\n",t[Get_Rank(read(),root)]); break;
case 5: printf("%d\n",t[Find(read(),1)]); break;
case 6: printf("%d\n",t[Find(read(),0)]); break;
}
return 0;
}
洛谷.3369.[模板]普通平衡树(Splay)的更多相关文章
- 洛谷.3391.[模板]文艺平衡树(Splay)
题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...
- 洛谷.3369.[模板]普通平衡树(fhq Treap)
题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...
- 【洛谷P3369】普通平衡树——Splay学习笔记(一)
二叉搜索树(二叉排序树) 概念:一棵树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉搜索树 ...
- 【洛谷P3391】文艺平衡树——Splay学习笔记(二)
题目链接 Splay基础操作 \(Splay\)上的区间翻转 首先,这里的\(Splay\)维护的是一个序列的顺序,每个结点即为序列中的一个数,序列的顺序即为\(Splay\)的中序遍历 那么如何实现 ...
- 在洛谷3369 Treap模板题 中发现的Splay详解
本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原 ...
- [洛谷日报第62期]Splay简易教程 (转载)
本文发布于洛谷日报,特约作者:tiger0132 原地址 分割线下为copy的内容 [洛谷日报第62期]Splay简易教程 洛谷科技 18-10-0223:31 简介 二叉排序树(Binary Sor ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
随机推荐
- spfa+01 规划
尼玛的哪里错了.. /* 在有向图上找一个环,使结点权值和/边权和的比例值最大 01规划,设比例为l,那么将每条边的权值改成a[u]-l*w,如果有正权环,则比例l可行 如何判图中存在正权环?将 权值 ...
- 登录界面之Axure原型制作
*****登录界面制作步骤***** 1.背景色:需要设定的背景色不知道色值,可以使用截图工具截取一小块粘贴到axure页面, 点击页面样式中的背景色左上角的取色器点击一下该色块,即可将背景色全部填充 ...
- SSM + Android 网络文件上传下载
SSM + Android 网络交互的那些事 2016年12月14日 17:58:36 ssm做为后台与android交互,相信只要是了解过的人都知道一些基本的数据交互,向json,对象,map的交互 ...
- python一个用例,多组参数,多个结果
在某种情况下,需要用不同的参数组合测试同样的行为,你希望从test case的执行结果上知道在测试什么,而不是单单得到一个大的 test case:此时如果仅仅写一个test case并用内嵌循环来进 ...
- 如何获取jar包的在执行机上面的路径
背景: 最近在项目中遇到一个小问题, 几行代码就能解决了 String path = this.getClass().getProtectionDomain().getCodeSource().get ...
- 史上最简单的SpringCloud教程 | 第七篇: 高可用的分布式配置中心(Spring Cloud Config)
上一篇文章讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如 ...
- tempalte模板
tempalte模板层: 功能:为了更有逻辑的将数据库中的数据渲染到模板中: 模拟数据源: DB = [ {"hostname":"c1.com"," ...
- 读C#开发实战1200例子记录-2017年8月14日10:03:55
C# 语言基础应用,注释 "///"标记不仅仅可以为代码段添加说明,它还有一项更重要的工作,就是用于生成自动文档.自动文档一般用于描述项目,是项目更加清晰直观.在VisualStu ...
- ExceptionLess的webAPI调用
引用 <package id="bootstrap" version="3.0.0" targetFramework="net461" ...
- Codeforces Round #506 (Div. 3)
题解: div3水的没有什么意思 abc就不说了 d题比较显然的就是用hash 但是不能直接搞 所以我们要枚举他后面那个数的位数 然后用map判断就可以了 刚开始没搞清楚数据范围写了快速乘竟然被hac ...