【替罪羊树】bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树
【替罪羊树】bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树
bzoj
洛谷
cogs
先长点芝士
替罪羊树也是一种很好写的平衡树qwq。。替罪羊树的核心思想就是重构。即当一棵子树的平衡被破坏,那么就把这棵树拍平,也就是树高为O(logn)的完美二叉树形态。这样看似复杂度很高,实则不然。可以证明,替罪羊树每次重构的复杂度都是均摊O(logn)的。
——蒯自WFJdalao的博客
插入和普通BST类似,只需要判断插入操作是否导致了这一条链上结点的大小平衡被破坏,如果有的话将深度最浅的点所在子树暴力重建。重建最简单的方法就是对这棵子树中序遍历后分治建树。通过势能分析可以证明每一次插入的均摊复杂度为\(logn\)。
查询和普通BST并无区别。
删除操作比较巧妙。对于一次删除,我们并不马上移除这个点,而是直接这个点上打上删除标记,查询时跳过该点。重构时可以顺便删除打了删除标记的点。当被删除结点的个数超过总结点数的\((1−α)\)倍时可以选择重构整棵树进行结构优化,并且显然这部分重构的复杂度不会超过\(O(nlogn)\)。
——蒯自xlightgod学长的博客
题解
上面说的很清楚了,然鹅我并不会“势能分析”呵呵哒
因为写treap写习惯了指针还挺好用的就尝试用指针写替罪羊树。。。我错了
然后我深陷二级指针的泥坑中无法自拔。。。
回归正题。。。
首先“拍平”就是把字树的中序遍历搞出来,然后暴力重建。。。好暴力
反正“可以证明,替罪羊树每次重构的复杂度都是均摊O(logn)的”,我不会证明。。。
Code
// It is made by XZZ
#include<cstdio>
#include<algorithm>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=1e6+2;
const double alpha=0.7777777;
int root,id,val[maxn],ch[maxn][2],siz[maxn],cover[maxn],b[maxn];
bool del[maxn];
il int newnode(int _val){val[++id]=_val,ch[id][0]=ch[id][1]=0,siz[id]=cover[id]=1;return id;}
il vd dfs(const int&rt){
if(!rt)return;
dfs(ch[rt][0]);
if(!del[rt])b[++b[0]]=rt;
dfs(ch[rt][1]);
}
il int divide(int l,int r){
if(l>r)return 0;
int mid=(l+r)>>1;
ch[b[mid]][0]=divide(l,mid-1);
ch[b[mid]][1]=divide(mid+1,r);
siz[b[mid]]=siz[ch[b[mid]][0]]+siz[ch[b[mid]][1]]+!del[b[mid]];
cover[b[mid]]=cover[ch[b[mid]][0]]+cover[ch[b[mid]][1]]+1;
return b[mid];
}
il vd rebuild(int&rt){
b[0]=0;dfs(rt);rt=divide(1,b[0]);
}
il int*_Insert(int&rt,const int&num){
if(!rt){rt=newnode(num);return NULL;}
++siz[rt],++cover[rt];
int*ret=_Insert(ch[rt][num>=val[rt]],num);
if(max(cover[ch[rt][0]],cover[ch[rt][1]])>alpha*cover[rt])ret=&rt;
return ret;
}
il vd Insert(const int&x){int*ls=_Insert(root,x);if(ls)rebuild(*ls);}
il int Rank(const int&x){
int ret=1,now=root;
while(now)
if(x<=val[now])now=ch[now][0];
else ret+=siz[ch[now][0]]+!del[now],now=ch[now][1];
return ret;
}
il int Kth(int k){
int now=root;
while(now){
if(!del[now]&&k==siz[ch[now][0]]+1)return val[now];
if(k<=siz[ch[now][0]])now=ch[now][0];
else k-=siz[ch[now][0]]+!del[now],now=ch[now][1];
}
}
il vd _Erase(int k){
int now=root;
while(now){
--siz[now];
if(!del[now]&&k==siz[ch[now][0]]+1){del[now]=1;return;}
if(k<=siz[ch[now][0]])now=ch[now][0];
else k-=siz[ch[now][0]]+!del[now],now=ch[now][1];
}
}
il vd Erase(const int&x){
_Erase(Rank(x));
if(siz[root]<cover[root]*alpha)rebuild(root);
}
int main(){
int n=gi(),opt,x;
while(n--){
opt=gi(),x=gi();
if(opt==1)Insert(x);
else if(opt==2)Erase(x);
else if(opt==3)printf("%d\n",Rank(x));
else if(opt==4)printf("%d\n",Kth(x));
else if(opt==5)printf("%d\n",Kth(Rank(x)-1));
else printf("%d\n",Kth(Rank(x+1)));
}
return 0;
}
【替罪羊树】bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树的更多相关文章
- (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
- bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5354 Solved: 2196[Submit][Sta ...
- [BZOJ3224]Tyvj 1728 普通平衡树
[BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...
- bzoj3224: Tyvj 1728 普通平衡树(平衡树)
bzoj3224: Tyvj 1728 普通平衡树(平衡树) 总结 a. cout<<(x=3)<<endl;这句话输出的值是3,那么对应的,在splay操作中,当父亲不为0的 ...
- BZOJ_3224 Tyvj 1728 普通平衡树 【离散化+权值线段树】
一 题面 Tyvj 1728 普通平衡树 二 分析 比较明显是可以用平衡二叉搜索树(splay)做的. 用权值线段树做,前提就是要先离散化,因为权值线段树维护的值域信息. 板子. 三 AC代码 #in ...
- BZOJ 3224: Tyvj 1728 普通平衡树 or 洛谷 P3369 【模板】普通平衡树-Splay树模板题
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 22483 Solved: 10130[Submit][S ...
- cogs 1829. [Tyvj 1728]普通平衡树 权值线段树
1829. [Tyvj 1728]普通平衡树 ★★★ 输入文件:phs.in 输出文件:phs.out 简单对比时间限制:1 s 内存限制:1000 MB [题目描述] 您需要写一种数 ...
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 7390 Solved: 3122 [Submit][S ...
- bzoj3224: Tyvj 1728 普通平衡树(splay)
3224: Tyvj 1728 普通平衡树 题目:传送门 题解: 啦啦啦啦又来敲个模版水经验啦~ 代码: #include<cstdio> #include<cstring> ...
随机推荐
- 2、Dubbo-核心概念
dubbo核心概念 2.1).简介 Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能.轻量级的开源Java RPC框架, 它提供了三大核心能力:面向接口的远程方法调用 ...
- SpringBoot实战(十三)之缓存
什么是缓存? 引用下百度百科的解释: 缓存就是数据交换的缓冲区(又称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,找到了则直接执行,找不到的话则从内存中查找.由于缓存的运行速度 ...
- oracle数据库之用户管理
转载 Oracle创建用户.角色.授权.建表 一.oracle数据库的权限系统分为系统权限与对象权限: 系统权限( database system privilege )可以让用户执行特定的命令集 ...
- Loadrunner之HTTP接口测试
Loadrunner之HTTP接口测试 接口测试的原理是通过测试程序模拟客户端向服务器发送请求报文,服务器接收请求报文后对相应的报文做出处理然后再把应答报文发送给客户端,客户端接收应答报文这一个过程. ...
- git 从远程仓克隆到本地新分支
克隆远程仓代码到本地 git clone http://******:8080/DEV1-WMALL_DQ/WMALL_DQ_Front.git // git 库地址 当前分支是master ...
- Adapter(适配器)模式
1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相关库的发展和进化. 例子1:iphone4,你即可以 ...
- yyy loves Easter_Egg I(恶心的字符串模拟)
题目背景 Soha的出题效率着实让人大吃一惊.OI,数学,化学的题目都出好了,物理的题还没有一道.于是,Huntfire,absi2011,redbag对soha进行轮番炸,准备炸到soha出来,不料 ...
- JavaScript日期格式转换
//日期格式转换 function dateFormat(val) {//val需要转换的日期 var fmt = "yyyy-MM-dd";//日期格式 val = val.re ...
- $.ajax(),$.get(),$.post()的区别,以及一些参数注意规则
$.ajax()方法和$.get(),$.post()方法的对比 $.ajax()方法是最完整的写法,可以完成所有的ajax请求(包含get类型和post类型) $.get()和$.post()都是简 ...
- PS中10种样式操作
(1)投影:将为图层上的对象.文本或形状后面添加阴影效果.投影参数由“混合模式”.“不透明度”.“角度”.“距离”.“扩展”和“大小”等各种选项组成,通过对这些选项的设置可以得到需要的效果. (2)内 ...