题解:

替罪羊树的模板和splay差距还是比较大的。。

按照我的splay的写法 真是都是问题。。

替罪羊树就是暴力的搞

当某颗子树大小大于这棵树的alpha时 就退出

另外删除的时候打懒标记删除

当有用个数少于alpha*n的时候,就重构

注意点:

1.找rank的时候要找比它小的个数,不能像splay那样取min

2.删除的时候要删排名为这个的,不能删这个数

以上两点的原因是

不能保证相同元素一定在左子树内,因为重构可能造成在右子树

另外找pre和scc也就不能和splay一样了

rank(x) 找的是编号最小的那个

rank(x)-1就是前驱

rank(x+1) 就是后继

替罪羊树不支持区间操作

应该写它的用处就是用来搞毒瘤树套树的。。

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define mid ((h+t)>>1)
const double alpha=0.75;
const int INF=2e9+;
const int N=4e6+;
int s[N],n,m,top,rt,t1;
struct phs{
int ls[N],rs[N],siz[N],travel[N],cnt[N],v[N];
bool f[N];
void dfs(int x)
{
if (!x) return;
dfs(ls[x]);
if (f[x]) travel[++t1]=x;
else s[++top]=x;
dfs(rs[x]);
}
void build(int &x,int h,int t)
{
x=travel[mid];
if (h==t)
{
siz[x]=cnt[x]=;
ls[x]=rs[x]=;
return;
}
if (h<mid) build(ls[x],h,mid-); else ls[x]=;
build(rs[x],mid+,t);
siz[x]=siz[ls[x]]+siz[rs[x]]+;
cnt[x]=cnt[ls[x]]+cnt[rs[x]]+;
}
void rebuild(int &x)
{
t1=; dfs(x);
if (t1) build(x,,t1);
else x=;
}
void insert(int &x,int k)
{
if (!x)
{
x=s[top--]; v[x]=k;
siz[x]=cnt[x]=f[x]=;
ls[x]=rs[x]=;
return;
}
siz[x]++; cnt[x]++;
if (k<=v[x]) insert(ls[x],k);
else insert(rs[x],k);
if ((double)max(siz[ls[x]],siz[rs[x]])>(double)siz[x]*alpha)
{
rebuild(x);
}
}
void del(int x,int k)
{
siz[x]--;
if (f[x]&&k==v[x])
{
f[x]=; return;
}
if (k<=v[x]) del(ls[x],k);
else del(rs[x],k);
}
void del(int k)
{
int now=rt;
while (now)
{
siz[now]--;
if (f[now]&&k==siz[ls[now]]+)
{
f[now]=;
return;
}
if (k<=siz[ls[now]]) now=ls[now];
else k-=siz[ls[now]]+f[now],now=rs[now];
}
}
void delete2(int x)
{
del(x);
if ((double)siz[rt]<(double) alpha*cnt[rt]) rebuild(rt);
}
int rank(int x)
{
int now=rt,ans=;
while (now)
{
if (v[now]>=x) now=ls[now];
else ans+=siz[ls[now]]+f[now],now=rs[now];
}
return(ans);
}
int get_kth(int x)
{
int now=rt;
while (now)
{
if (f[now]&&x==siz[ls[now]]+) return(v[now]);
if (siz[ls[now]]>=x) now=ls[now];
else x-=siz[ls[now]]+f[now],now=rs[now];
}
}
}S;
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
dep(i,,) s[++top]=i;
rep(i,,n)
{
// cout<<i<<endl;
int kk,x;
cin>>kk>>x;
if (kk==)
{
S.insert(rt,x);
}
if (kk==)
{
S.delete2(S.rank(x));
}
if (kk==)
{
cout<<S.rank(x)<<endl;
}
if (kk==)
{
cout<<S.get_kth(x)<<endl;
}
if (kk==)
{
cout<<S.get_kth(S.rank(x)-)<<endl;
}
if (kk==)
{
cout<<S.get_kth(S.rank(x+))<<endl;
}
}
return ;
}

https://zhuanlan.zhihu.com/p/21263304

替罪羊树&&非旋treap的更多相关文章

  1. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

  2. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  3. 非旋treap套线段树

    BZOJ3065. 去年用pascal 块链过了.. 今年来试了试非旋treap大法   注定被块链完爆 代码留这. 第一份 :辣鸡的  垃圾回收做法  跑得极慢 #include <bits/ ...

  4. 非旋 treap 结构体数组版(无指针)详解,有图有真相

    非旋  $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ  ...

  5. 2827: 千山鸟飞绝 非旋treap

    国际惯例的题面:看起来很不可做的样子,我们先来整理一下题意吧.就是,维护每个点曾经拥有过的最大的两个属性值,支持把点的位置移动.我们用map对每个位置进行离散化,对每个位置建立一个平衡树.为了方便分离 ...

  6. 2018.08.06 bzoj1500: [NOI2005]维修数列(非旋treap)

    传送门 平衡树好题. 我仍然是用的fhqtreap,感觉速度还行. 维护也比线段树splay什么的写起来简单. %%%非旋treap大法好. 代码: #include<bits/stdc++.h ...

  7. 非旋Treap总结 : 快过Splay 好用过传统Treap

    非旋$Treap$ 其高级名字叫$Fhq\ Treap$,既然叫$Treap$,它一定满足了$Treap$的性质(虽然可能来看这篇的人一定知道$Treap$,但我还是多说几句:$Fhp\ Treap$ ...

  8. 非旋treap

    目录 核心思想 核心操作 其他操作 参考程序 核心思想 主要的思想与treap是一样的.通过让二叉查找树同时满足堆(随机参数)的性质来防止深度过大.与普通treap不同的是非旋treap通过树的分裂与 ...

  9. 非旋Treap及其可持久化

    平衡树这种东西,我只会splay.splay比较好理解,并且好打,操作方便. 我以前学过SBT,但并不是很理解,所以就忘了怎么打了. 许多用平衡树的问题其实可以用线段树来解决,我们真正打平衡树的时候一 ...

随机推荐

  1. Git学习笔记01-安装Git

    学习的资料来自廖雪峰官方网站的Git教程,菜鸟教程的Git教程 Git是一个分布式版本控制工具,在windows上使用Git可以直接从官网下载,然后默认选项安装即可. 安装完成后,在开始菜单中找到找到 ...

  2. requests库入门02-简单了解HTTP协议

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议. HTT ...

  3. JavaScript拼接html字符串时截断问题

    在项目中碰到一个问题,就是JavaScript拼接html标签时,里面特殊字符会有些问题,比如单引号截断配对,导致后面的内容不显示或显示错误.在此记录一下. 下面贴一段简化的代码,若有描述不清的地方还 ...

  4. 深入学习NAT工作原理

    深入学习NAT工作原理 我们单位中的电脑很多,组成了一个局域网,网络中只有一个电脑和外网(Internet)相连,当然有一个外网地址,但仅仅一个.我以前一直不明白,我们局域网的电脑均能上网,几台同时上 ...

  5. Statically Linking freeglut

    It’s possible statically link freeglut into your applications, instead of dynamically linking agains ...

  6. 8)django-示例(url传递参数)

    url传递参数有两种,一个是通过普通分组方式,一个是通过带命名分组方式 1.传递方式 1)普通分组方式,传递参数顺序是严格的.如下例子 url(r'^detail-(\d+)-(\d+).html', ...

  7. 微信小程序UI组件--Lin UI

    地址:http://doc.mini.7yue.pro/ Lin UI 是基于 微信小程序原生语法 实现的组件库

  8. 清北学堂 清北-Day1-R2-监听monitor

    题目描述 [背景] 不阅读本题的[背景]并不影响通过本题. 三体信息中没有包含对三体⼈⽣物形态的任何描述,⼈类要在四百多年以后才能真正看到三体⼈.在阅读信息时,叶⽂洁只能把三体⼈想象成⼈类的形象. 1 ...

  9. idea 去除xml文件sql语句背景色

    怎么看idea mapper.xml中写sql语句的那种屎黄屎黄背景颜色不好看 去除背景色 把这两项勾选去掉,然后 把这个背景勾选也去掉,最后 把这个勾选也去掉 另一种方式: 也可以使用这种方式 al ...

  10. 基础常用的数据结构 Collection Map

    map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等.其中这四者的区别如下(简单介绍): HashMap:我们最常用的Map ...