BZOJ3224/洛谷P3391 - 普通平衡树(Splay)
题意简述
模板题啦~
代码
//普通平衡树(Splay)
#include <cstdio>
int const N=1e5+10;
int rt,ndCnt;
int ch[N][2],fa[N],val[N],siz[N],cnt[N];
int wh(int p) {return p==ch[fa[p]][1];}
void create(int p,int v) {ch[p][0]=ch[p][1]=fa[p]=0; val[p]=v; cnt[p]=1,siz[p]=1;}
void update(int p) {if(p) siz[p]=cnt[p]+siz[ch[p][0]]+siz[ch[p][1]]; else siz[p]=0;}
void rotate(int p)
{
int q=fa[p],r=fa[q],w=wh(p);
fa[ch[q][w]=ch[p][w^1]]=q;
fa[ch[p][w^1]=q]=p;
fa[p]=r; if(r) ch[r][q==ch[r][1]]=p;
update(p),update(q);
}
void splay(int p)
{
for(int q;q=fa[p];rotate(p)) if(fa[q]) rotate(wh(p)==wh(q)?q:p);
update(rt=p);
}
int find(int v)
{
int p=rt,res=0;
while(true)
if(val[p]>v) p=ch[p][0];
else
{
res+=siz[ch[p][0]];
if(val[p]==v) {splay(p); return res+1;}
res+=cnt[p],p=ch[p][1];
}
}
int rank(int x)
{
int p=rt;
while(true)
if(siz[ch[p][0]]>=x) p=ch[p][0];
else
{
int sizL=siz[ch[p][0]]+cnt[p];
if(sizL>=x) return val[p];
x-=sizL,p=ch[p][1];
}
}
int pre(int v)
{
int p=rt,res;
while(p)
if(val[p]<v) res=val[p],p=ch[p][1];
else p=ch[p][0];
return res;
}
int nxt(int v)
{
int p=rt,res;
while(p)
if(val[p]>v) res=val[p],p=ch[p][0];
else p=ch[p][1];
return res;
}
void ins(int v)
{
if(rt==0) {create(rt=++ndCnt,v); return;}
int p=rt,q=0;
while(true)
{
if(val[p]==v) {cnt[p]++; update(p),update(q); splay(p); break;}
q=p; p=ch[p][val[p]<v];
if(p==0)
{
create(++ndCnt,v);
fa[ch[q][val[q]<v]=ndCnt]=q;
update(q); splay(ndCnt);
break;
}
}
}
void del(int v)
{
int p=rt;
while(true)
if(val[p]==v) break;
else p=ch[p][val[p]<v];
splay(p);
if(cnt[p]>1) {cnt[p]--; return;}
int sCnt=(ch[p][0]>0)+(ch[p][1]>0);
if(sCnt==0) rt=0;
if(sCnt==1) fa[rt=ch[p][ch[p][0]==0]]=0;
if(sCnt==2)
{
int q=ch[p][0];
while(ch[q][1]) q=ch[q][1];
splay(q);
fa[ch[q][1]=ch[p][1]]=q;
update(q);
}
ch[p][0]=ch[p][1]=0; fa[p]=-1;
}
int main()
{
int q; scanf("%d",&q);
while(q--)
{
int opt,x;
scanf("%d%d",&opt,&x);
//printf("\n-------- %d %d Begin.\n",opt,x);
if(opt==1) ins(x);
if(opt==2) del(x);
if(opt==3) printf("%d\n",find(x));
if(opt==4) printf("%d\n",rank(x));
if(opt==5) printf("%d\n",pre(x));
if(opt==6) printf("%d\n",nxt(x));
//for(int i=1;i<=ndCnt;i++) printf("%d fa=%d son=%d,%d val=%d siz=%d cnt=%d\n",i,fa[i],ch[i][0],ch[i][1],val[i],siz[i],cnt[i]);
}
return 0;
}
Version2
//普通平衡树
#include <cstdio>
#include <algorithm>
using namespace std;
inline char gc()
{
static char now[1<<16],*S,*T;
if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
return *S++;
}
inline int read()
{
int x=0,f=1; char ch=gc();
while(ch<'0'||'9'<ch) {if(ch=='-') f=-1; ch=gc();}
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int const N=1e5+10;
int const INF=0x7FFFFFFF;
int rt,ndCnt;
int fa[N],ch[N][2],val[N],cnt[N],siz[N];
int wh(int p) {return p==ch[fa[p]][1];}
void update(int p) {siz[p]=siz[ch[p][0]]+cnt[p]+siz[ch[p][1]];}
void create(int p,int x) {fa[p]=ch[p][0]=ch[p][1]=0; val[p]=x,cnt[p]=siz[p]=1;}
void rotate(int p)
{
int q=fa[p],r=fa[q],w=wh(p);
fa[ch[q][w]=ch[p][w^1]]=q;
fa[p]=r; if(r) ch[r][wh(q)]=p;
fa[ch[p][w^1]=q]=p;
update(p),update(q);
}
void splay(int p,int &k)
{
int r=fa[k];
for(int q;(q=fa[p])!=r;rotate(p)) if(fa[q]!=r) rotate(wh(p)==wh(q)?q:p);
update(k=p);
}
void ins(int x)
{
int p=rt,q=0;
while(p&&val[p]!=x) q=p,p=ch[p][val[p]<x];
if(p) {splay(p,rt),cnt[rt]++,siz[rt]++; return;}
create(p=++ndCnt,x);
fa[p]=q; if(q) ch[q][val[q]<x]=p,update(q);
splay(p,rt);
}
void del(int x)
{
int p=rt; while(val[p]!=x) p=ch[p][val[p]<x];
splay(p,rt); if(cnt[p]>1) {cnt[rt]--,siz[rt]--; return;}
if(ch[p][0]*ch[p][1]==0) {fa[rt=ch[p][ch[p][1]>0]]=0; return;}
int q=ch[p][0]; while(ch[q][1]) q=ch[q][1];
splay(q,rt); fa[ch[rt][1]=ch[p][1]]=rt;
}
int find(int x)
{
int p,res=0;
for(p=rt;val[p]!=x;p=ch[p][val[p]<x])
if(val[p]<x) res+=siz[ch[p][0]]+cnt[p];
return res+siz[ch[p][0]]+1;
}
int rank(int x)
{
int p=rt,res=0;
while(true)
{
int sizL=siz[ch[p][0]]+cnt[p];
if(x<=siz[ch[p][0]]) p=ch[p][0];
else if(x<=sizL) return val[p];
else x-=sizL,p=ch[p][1];
}
}
int pre(int x)
{
int res=-INF;
for(int p=rt;p;p=ch[p][val[p]<x])
if(val[p]<x) res=max(res,val[p]);
return res;
}
int nxt(int x)
{
int res=INF;
for(int p=rt;p;p=ch[p][val[p]<=x])
if(val[p]>x) res=min(res,val[p]);
return res;
}
int main()
{
int T=read();
while(T--)
{
int opt=read(),x=read();
if(opt==1) ins(x);
else if(opt==2) del(x);
else if(opt==3) printf("%d\n",find(x));
else if(opt==4) printf("%d\n",rank(x));
else if(opt==5) printf("%d\n",pre(x));
else if(opt==6) printf("%d\n",nxt(x));
}
return 0;
}
BZOJ3224/洛谷P3391 - 普通平衡树(Splay)的更多相关文章
- [洛谷P3391] 文艺平衡树 (Splay模板)
初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...
- 洛谷P3391文艺平衡树(Splay)
题目传送门 转载自https://www.cnblogs.com/yousiki/p/6147455.html,转载请注明出处 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 ...
- BZOJ3223/洛谷P3391 - 文艺平衡树
BZOJ链接 洛谷链接 题意 模板题啦~2 代码 //文艺平衡树 #include <cstdio> #include <algorithm> using namespace ...
- 洛谷 P3391 文艺平衡树
题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 --b ...
- 洛谷P3391 文艺平衡树 (Splay模板)
模板题. 注意标记即可,另外,涉及区间翻转操作,记得设立首尾哨兵. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int ...
- 洛谷 P3391 【模板】文艺平衡树(Splay)
题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
- (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
- 洛谷P3369普通平衡树(Treap)
题目传送门 转载自https://www.cnblogs.com/fengzhiyuan/articles/7994428.html,转载请注明出处 Treap 简介 Treap 是一种二叉查找树.它 ...
随机推荐
- redis集群主从集群搭建、sentinel(哨兵集群)配置以及Jedis 哨兵模式简要配置
前端时间项目上为了提高平台性能,为应用添加了redis缓存,为了提高服务的可靠性,redis部署了高可用的主从缓存,主从切换使用的redis自带的sentinel集群.现在权作记录.
- Linux指令--rcp,scp
rcp代表"remote file copy"(远程文件拷贝).该命令用于在计算机之间拷贝文件.rcp命令有两种格式.第一种格式用于文件到文件的拷贝:第二种格式用于把文件或目录拷贝 ...
- PHP获取客户端和服务器端IP(转)
客户端的ip变量: $_SERVER['REMOTE_ADDR'] :客户端IP,也有可能是代理IP $_SERVER['HTTP_CLIENT_IP']:代理端的IP,可能存在,也可能伪造 $_SE ...
- 《css定位 position》课程笔记
这是我学习课程css定位 position时做的笔记! 本节内容 html的三种布局方式 position可选参数 z-index 盒子模型和定位的区别 侧边栏导航跟随实例 html的三种布局方式 三 ...
- Git Batch命令(转)
echo 和 @ 回显命令 @ #关闭单行回显 echo off #从下一行开始关闭回显 @echo off #从本行开始关闭回显.一般批处理第一行都是这个 echo on #从下一行开始打开回显 e ...
- C之多线程(例子很不错)
1.线程 线程池是一个树状结构. 多线程解决并发问题. 一个线程内部的执行顺序是线性的.而线程之间是乱序的. 若要创建一个多线程程序,它的参数必须是空指针类型. 变色龙程序: #define _CRT ...
- Snort初探
Snort初探 概念: Snort是一款开源的网络入侵防御系统(IPS),可以实时分析和记录网络数据包,你可以通过执行协议分析.内容搜索和匹配,从而发现各种网络攻击和可疑的探测.例如,缓冲区溢出.端口 ...
- Linux下查看CPU、内存和硬盘信息命令
一.查看cpu信息 cat /proc/cpuinfo 相同physical id 的记录是属于同一个CPU的,对应于多核的信息. 二.查看内存的信息 cat /proc/meminfo 三.查看硬盘 ...
- BZOJ 4518: [Sdoi2016]征途 [斜率优化DP]
4518: [Sdoi2016]征途 题意:\(n\le 3000\)个数分成m组,一组的和为一个数,求最小方差\(*m^2\) DP方程随便写\(f[i][j]=min\{f[k][j-1]+(s[ ...
- 设计模式之“Decorator”注疏#02
装饰模式在某种意义上来说也是挺原始的, 它首先需要一个你被装饰的基础类, 再来是需要一个基于这个基础类的原始包装器,可以看作是其它包装器的基础类 进而通过继承这个包装器,来构建出多个具有各自功能的特定 ...