Luogu 3369 / BZOJ 3224 - 普通平衡树 - [替罪羊树]
题目链接:
https://www.lydsy.com/JudgeOnline/problem.php?id=3224
https://www.luogu.org/problemnew/show/P3369
Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作3,4,5,6每行输出一个数,表示对应答案
Sample Input
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
106465
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
关于替罪羊树:
替罪羊树的主要思想就是将不平衡的树压成一个序列,然后暴力重构成一颗平衡的树。
这里的平衡指的是:对于某个 $0.5 \le \alpha \le 1$ 满足 $size( ls(x) ) \le \alpha \cdot size(x)$ 并且 $size( rs(x) ) \le \alpha \cdot size(x)$。一般 $\alpha$ 取 $0.7 \sim 0.8$。
更加详细的解释和模板请参考替罪羊树(重量平衡树)入门
AC代码:
#include<bits/stdc++.h>
using namespace std; const int maxn=1e5+;
const double alpha=0.8;
struct Node
{
Node* ch[]; //左右子节点
int key,siz,cov; //key是值,siz是以该节点为根的树的存在的节点数,cover是所有节点数量
bool ext;
void pushup() { //更新函数
siz = ch[]->siz + ch[]->siz + ext;
cov = ch[]->cov + ch[]->cov + ;
}
inline bool isbad() { //判断是否要重构
return alpha*cov+ < max(ch[]->cov,ch[]->cov);
}
};
struct ScapegoatTree
{
protected:
Node mem[maxn]; //内存池
Node *tail,*null,*root; //tail为指向内存池元素的指针
Node *bak[maxn]; int baksz; //内存回收池 Node* newnode(int key)
{
Node* p=baksz?bak[--baksz]:tail++;
p->ch[] = p->ch[] = null;
p->siz = p->cov= p->ext = ;
p->key = key;
return p;
} void travel(vector<Node*>& v,Node* p) //中序遍历将一棵树转化成序列
{
if(p==null) return;
travel(v,p->ch[]);
if(p->ext) v.push_back(p);
else bak[baksz++]=p;
travel(v,p->ch[]);
} Node* build(vector<Node*>& v,int l,int r)
{
if(l>=r) return null;
int mid=(l+r)>>;
Node *p=v[mid];
p->ch[] = build(v,l,mid);
p->ch[] = build(v,mid+,r);
p->pushup();
return p;
} vector<Node*> cur;
void rebuild(Node*& p)
{
cur.clear();
travel(cur,p);
p=build(cur,,cur.size());
} Node** insert(Node*& p,int val)
{
if(p==null)
{
p=newnode(val);
return &null;
}
p->siz++, p->cov++;
Node** res=insert(p->ch[val>=p->key],val);
if(p->isbad()) res=&p;
return res;
} void erase(Node*& p,int k)
{
p->siz--; //维护siz
int offset = p->ch[]->siz + p->ext; //计算左子树的存在的节点总数
if(p->ext && k==offset) p->ext=;
else
{
if(k<=offset) erase(p->ch[],k);
else erase(p->ch[],k-offset);
}
} public:
void init()
{
tail=mem;
null=tail++;
null->ch[] = null->ch[] = null;
null->key = ;
null->siz = null->cov = null->ext = ;
root=null; //初始化根节点
baksz=; //清空栈
}
ScapegoatTree() {
init();
} void insert(int val)
{
Node** res=insert(root,val);
if(*res!=null) rebuild(*res);
} int getrank(int val)
{
Node *p=root;
int res=;
while(p!=null)
{
if(val <= p->key) p=p->ch[];
else
{
res += p->ch[]->siz + p->ext;
p = p->ch[];
}
}
return res;
} int getkth(int k)
{
Node *p=root;
while(p!=null)
{
if(p->ch[]->siz+==k && p->ext) return p->key;
if(k <= p->ch[]->siz) p=p->ch[];
else k-=p->ch[]->siz + p->ext, p=p->ch[];
}
} void delval(int val)
{
erase(root,getrank(val));
if(root->siz < alpha * root->cov) rebuild(root);
} void delkth(int k)
{
erase(root,k);
if(root->siz < alpha * root->cov) rebuild(root);
}
}st; int main()
{
int n,opt,x;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&opt,&x);
if(opt==) st.insert(x);
if(opt==) st.delval(x);
if(opt==) printf("%d\n",st.getrank(x));
if(opt==) printf("%d\n",st.getkth(x));
if(opt==) printf("%d\n",st.getkth(st.getrank(x)-));
if(opt==) printf("%d\n",st.getkth(st.getrank(x+)));
}
}
Luogu 3369 / BZOJ 3224 - 普通平衡树 - [替罪羊树]的更多相关文章
- Luogu 3369 / BZOJ 3224 - 普通平衡树 - [无旋Treap]
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 https://www.luogu.org/problemnew/show/P3 ...
- BZOJ 3224 普通平衡树(树状数组)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3224 题意:维护以下操作:(1)插入x:(2)删除x(若有多个相同的数,只删除一个)(3 ...
- bzoj 3224: Tyvj 1728 普通平衡树 替罪羊树
题目链接 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的 ...
- BZOJ 3435 / Luogu 3920 [WC2014]紫荆花之恋 (替罪羊树 动态点分治 套 Treap)
题意 略 分析 引用PoPoQQQ的话 吾辈有生之年终于把这道题切了...QAQ (蒟蒻狂笑) Orz PoPoQQQ,我又抄PoPoQQQ的题解了 - 突然发现有旋Treap没那么难写 学习了一波C ...
- BZOJ 3224 普通平衡树(Treap模板题)
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 14301 Solved: 6208 [Submit][ ...
- [TYVJ1728/BZOJ3224]普通平衡树-替罪羊树
Problem 普通平衡树 Solution 本题是裸的二叉平衡树.有很多种方法可以实现.这里打的是替罪羊树模板. 此题极其恶心. 前驱后继模块需要利用到rank模块来换一种思路求. 很多细节的地方容 ...
- 平衡树 替罪羊树(Scapegoat Tree)
替罪羊树(Scapegoat Tree) 入门模板题 洛谷oj P3369 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入xx数 删除xx数(若有多个相同 ...
- bzoj2827: 千山鸟飞绝 平衡树 替罪羊树 蜜汁标记
这道题首先可以看出坐标没有什么意义离散掉就好了. 然后你就会发现你要每次都更改坐标,而一旦更改受影响的是坐标里的所有数,要是一个一个的改,会不可描述. 所以换个视角,我们要找的是某只鸟所到每个坐标时遇 ...
- BZOJ 3224 - 普通平衡树 - [Treap][Splay]
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中 ...
随机推荐
- C++11中的右值引用及move语义编程
C++0x中加入了右值引用,和move函数.右值引用出现之前我们只能用const引用来关联临时对象(右值)(造孽的VS可以用非const引用关联临时对象,请忽略VS),所以我们不能修临时对象的内容,右 ...
- JAVA之Lamdba表达式使用摘要
1. of (of方法其生成的Stream是有限长度的,Stream的长度为其内的元素个数) Stream<Integer> integerStream = Stream.of(1, ...
- 游戏编程精粹学习 - 使用Bloom过滤来提高计算性能(BloomFilter)
原文在<游戏编程精粹2>的1.2中,BloomFilter是一种可以快速检测是否存在集合包含关系的数据结构,但有一定的误识别率. 该结构的优点 判断包含关系时效率较高,粗略测试了下比Lis ...
- Atitit.每周计划日程表 流程表v3
Atitit.每周计划日程表 流程表 每周趋势总结 新特性聚合 最佳实践聚合. 上周总结 本度计划 检查于推进年度计划月度计划里程碑 检查于推进季度计划月度计划里程碑 上周Todo汇总结转.. 待报 ...
- [svc]linux下网桥-docker网桥
网桥和交换机 2口交换机=网桥 交换机: 工作在数据链路层,根据源mac学习(控制层),目的mac转发(数据层). linux的网卡 vmware workstation中的桥接 参考: http:/ ...
- ASP.NET Core Razor Pages
Razor 页面是Asp.Net Core2.0新增的一个功能.Razor 页面是 ASP.NET Core MVC 的一个新特性,它可以使基于页面的编码方式更简单高效. 环境:vs2017 .net ...
- Java知多少(33)多态对象的类型转换
这里所说的对象类型转换,是指存在继承关系的对象,不是任意类型的对象.当对不存在继承关系的对象进行强制类型转换时,java 运行时将抛出 java.lang.ClassCastException 异常. ...
- CLOS网络
CLOS网络是指为了降低多级交换网络的成本,长期以来人们一直在寻找一种交叉点数随入.出现数增长较慢的交换网络,其基本思想都是采用多个较小规模的交换单元按照某种连接方式连接起来形成多级交换网络.
- 详解Linux安装GCC
为你详解Linux安装GCC方法 2009-12-11 14:05 佚名 博客园 字号:T | T 现在很多程序员都应用GCC,怎样才能更好的应用GCC.本文以在Redhat Linux安装GCC4. ...
- 大数据基础篇----jvm的知识点归纳-5个区和垃圾回收机制
一直对jvm看了又忘,忘了又看的.今天做一个笔记整理存放在这里. 我们先看一下JVM的内存模型图: 上面有5个区,这5个区干嘛用的呢? 我们想象一个场景: 我们有一个class文件,里面有很多的类的定 ...