替罪羊树模板(封装版)-----转自知乎
https://zhuanlan.zhihu.com/p/21263304
里面有关于替罪羊树的详细介绍,这里就不再赘述。
#include <vector> #include <cstdio> #include <iostream> using namespace std;namespace Scapegoat_Tree {#define MAXN (100000 + 10)const double alpha = 0.75;struct Node{Node *ch[2];int key, sz, cover;bool exist;void pushup(){sz = ch[0]->sz + ch[1]->sz + (int)exist;cover = ch[0]->cover + ch[1]->cover + 1;}bool isbad(){return (ch[0]->cover > cover * alpha + 5)||(ch[1]->cover > cover * alpha + 5);}};struct STree{protected:Node mem_poor[MAXN];Node *tail, *root, *null;Node *bc[MAXN];int bc_top;Node * Newnode(int key){Node *p = bc_top ? bc[--bc_top] : tail++;p->ch[0] = p->ch[1] = null;p->sz = p->cover = 1; p->exist = true;p->key = key;return p;}void Travel(Node *p, vector<Node *> &v){if(p == null) return;Travel(p->ch[0], v);if(p->exist) v.push_back(p);else bc[bc_top++] = p;Travel(p->ch[1], v);}Node* Divide(vector<Node *> &v, int l, int r){if(l >= r) return null;int mid = (l+r)>>1;Node *p = v[mid];p->ch[0] = Divide(v, l, mid);p->ch[1] = Divide(v, mid+1, r);p->pushup();return p;}void Rebuild(Node *& p){static vector<Node *>v; v.clear();Travel(p, v); p = Divide(v, 0, v.size());}Node ** Insert(Node *&p, int val){if(p == null){p = Newnode(val);return &null;}else{p->sz++; p->cover++;Node **res = Insert(p->ch[val >= p->key], val);if(p->isbad()) res = &p;return res;}}void Erase(Node *p, int id){p->sz--;int offset = p->ch[0]->sz + p->exist;if(p->exist && id == offset){p->exist = false;return;}else{if(id <= offset) Erase(p->ch[0], id);else Erase(p->ch[1], id - offset);}}public:void init(){tail = mem_poor;null = tail++;null->ch[0] = null->ch[1] = null;null->cover = null->sz = null->key = 0;root = null; bc_top = 0;}void Insert(int val){Node **p = Insert(root, val);if(*p != null) Rebuild(*p);}int Rank(int val){Node *now = root;int ans = 1;while(now != null){if(now->key >= val) now = now->ch[0];else{ans += now->ch[0]->sz + now->exist;now = now->ch[1];}}return ans;}int Kth(int k){Node *now = root;while(now != null){if(now->ch[0]->sz + 1 == k && now->exist) return now->key;else if(now->ch[0]->sz >= k) now = now->ch[0];else k -= now->ch[0]->sz + now->exist, now = now->ch[1];}return 0;}void Erase(int k){Erase(root, Rank(k));if(root->sz < alpha*root->cover) Rebuild(root);}void Erase_kth(int k){Erase(root, k);if(root->sz < alpha * root->cover) Rebuild(root);}};#undef MAXN } using namespace Scapegoat_Tree; STree root; int main() {int T, x, y; cin>>T; root.init();while(T--){scanf("%d %d", &x, &y);switch(x){case 1: root.Insert(y); break;case 2: root.Erase(y); break;case 3: printf("%d\n", root.Rank(y)); break;case 4: printf("%d\n", root.Kth(y)); break;case 5: printf("%d\n", root.Kth(root.Rank(y)-1)); break;case 6: printf("%d\n", root.Kth(root.Rank(y+1))); break;}} }
转载于:https://www.cnblogs.com/Saurus/p/6086509.html
替罪羊树模板(封装版)-----转自知乎相关推荐
- 替罪羊树+3369 【模板】普通平衡树
传送门 一听是平衡树 就jio的很难很难 然而大佬说很简单 (听的时候确实jio的没有想象中的那么难<大佬讲的好orz) 然而 写代码的时候就完全不是了 足足花了我两个晚上啊 终于整的差不多明白 ...
- 【替罪羊树及其应用】替罪羊树总结
update:退役后对这篇文章进行了一些更新,主要增加了一个后缀平衡树的版块.很遗憾的,csp的350给我的OI生涯画上了句号.记得联赛前大概写了10遍平衡树模板,遗憾没有用上.不过代码经过联赛前反复 ...
- Tablacus Explorer双心封装版
Tablacus Explorer双心封装版 http://cloud.189.cn/t/mYj67j7r2Afq (TablacusExplorer17.3.27双心封装版.exe) http:// ...
- 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树
题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...
- P1276 校门外的树(增强版)(线段树)(校门三部曲)难度⭐⭐⭐
校门三部曲,总算完结了!完结散花! 难度呈阶梯状,都可以用线段树解决. 第一部 P1047 校门外的树(线段树优化)难度⭐⭐ 第二部 P1276 校门外的树(增强版)(线段树)校门三部曲难度⭐⭐⭐ 第 ...
- python 回溯法 子集树模板 系列 —— 3、0-1背包问题
问题 给定N个物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大? 分析 显然,放入背包的物品,是N个物品的所有子集的其 ...
- python 回溯法 子集树模板 系列 —— 5、取物搭配问题
问题 有5件不同的上衣,3条不同的裤子,4顶不同的帽子,从中取出一顶帽子.一件上衣和一条裤子作为一种搭配,问有多少种不同的搭配? 分析 换个角度看,现有头.身.腿三个元素,每个元素都有各自的几种状态. ...
- (2014年2月7日升级)Ubuntu-14.04-Alpha2-32位简体中文优化封装版
2019独角兽企业重金招聘Python工程师标准>>> (2014年2月7日升级)Ubuntu-14.04-Alpha2-32位简体中文优化封装版 感谢大家对LINUX封装技术的支持 ...
- 函数模板案例_利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试
案例描述: 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试 #include <iostream& ...
- poj2104(划分树模板)
poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...
最新文章
- Java微框架Spring Boot 运行原理深入解读
- CLion 远程Linux服务器 开发调试
- SAP Spartacus user form页面的css设计重构
- java 队列 array_Java源码解析阻塞队列ArrayBlockingQueue常用方法
- 巧用ActionFilter的AOP特性,为返回的数据增加返回码和消息
- block的理解 ios_iOS面试--字节跳动最新iOS开发面试题
- mysql 执行时间有波动_阿里P8架构师谈mysql性能优化思路
- Atitit. camel分词器 分词引擎 camel拆分 的实现设计
- vss 2005 配置服务器端的时候提示IIS没有安装
- 【ArcGIS教程01】前言
- 全球十大机器人运动控制品牌
- ImageAI训练自定义数据总结
- C# Abp框架入门系列文章(一)
- 制作纯净系统U盘教程(详细版)
- javacc jjtree 写法 以及 jj写法 基本语法 以及应用
- C语言学习笔记《带你学C带你飞》P41-P61
- 切蛋糕java题,【算法•日更•第六期】头脑风暴:洛谷P1528 切蛋糕题解
- msfvenom生成木马的简单利用
- 麻将番型计算(二人麻将)
- osgEarth示例分析——osgearth_annotation
热门文章
- numpy教程:数学函数和基本统计函数
- java第七章jdbc课后简答题_Java进阶之JDBC面试题(7)
- 怎样调整input框背景颜色_还在用百度搜索PPT背景图?7个高大上的图片网站,个个都是高清免费无版权!...
- android 打包问题,Android离线打包常见问题
- 蓝桥杯2017年第八届C/C++省赛C组第八题-九宫幻方
- 力扣-1232 缀点成线
- 使用 Multipath TCP 为 iOS 创建备份连接(转)
- 开源协议的几种类型认识
- Android Application基本组成部分
- DataAdapter对象填充数据集