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

替罪羊树模板(封装版)-----转自知乎相关推荐

  1. 替罪羊树+3369 【模板】普通平衡树

    传送门 一听是平衡树 就jio的很难很难 然而大佬说很简单 (听的时候确实jio的没有想象中的那么难<大佬讲的好orz) 然而 写代码的时候就完全不是了 足足花了我两个晚上啊 终于整的差不多明白 ...

  2. 【替罪羊树及其应用】替罪羊树总结

    update:退役后对这篇文章进行了一些更新,主要增加了一个后缀平衡树的版块.很遗憾的,csp的350给我的OI生涯画上了句号.记得联赛前大概写了10遍平衡树模板,遗憾没有用上.不过代码经过联赛前反复 ...

  3. Tablacus Explorer双心封装版

    Tablacus Explorer双心封装版 http://cloud.189.cn/t/mYj67j7r2Afq (TablacusExplorer17.3.27双心封装版.exe) http:// ...

  4. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  5. P1276 校门外的树(增强版)(线段树)(校门三部曲)难度⭐⭐⭐

    校门三部曲,总算完结了!完结散花! 难度呈阶梯状,都可以用线段树解决. 第一部 P1047 校门外的树(线段树优化)难度⭐⭐ 第二部 P1276 校门外的树(增强版)(线段树)校门三部曲难度⭐⭐⭐ 第 ...

  6. python 回溯法 子集树模板 系列 —— 3、0-1背包问题

    问题 给定N个物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大? 分析 显然,放入背包的物品,是N个物品的所有子集的其 ...

  7. python 回溯法 子集树模板 系列 —— 5、取物搭配问题

    问题 有5件不同的上衣,3条不同的裤子,4顶不同的帽子,从中取出一顶帽子.一件上衣和一条裤子作为一种搭配,问有多少种不同的搭配? 分析 换个角度看,现有头.身.腿三个元素,每个元素都有各自的几种状态. ...

  8. (2014年2月7日升级)Ubuntu-14.04-Alpha2-32位简体中文优化封装版

    2019独角兽企业重金招聘Python工程师标准>>> (2014年2月7日升级)Ubuntu-14.04-Alpha2-32位简体中文优化封装版 感谢大家对LINUX封装技术的支持 ...

  9. 函数模板案例_利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试

    案例描述: 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试 #include <iostream& ...

  10. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

最新文章

  1. Java微框架Spring Boot 运行原理深入解读
  2. CLion 远程Linux服务器 开发调试
  3. SAP Spartacus user form页面的css设计重构
  4. java 队列 array_Java源码解析阻塞队列ArrayBlockingQueue常用方法
  5. 巧用ActionFilter的AOP特性,为返回的数据增加返回码和消息
  6. block的理解 ios_iOS面试--字节跳动最新iOS开发面试题
  7. mysql 执行时间有波动_阿里P8架构师谈mysql性能优化思路
  8. Atitit. camel分词器 分词引擎 camel拆分 的实现设计
  9. vss 2005 配置服务器端的时候提示IIS没有安装
  10. 【ArcGIS教程01】前言
  11. 全球十大机器人运动控制品牌
  12. ImageAI训练自定义数据总结
  13. C# Abp框架入门系列文章(一)
  14. 制作纯净系统U盘教程(详细版)
  15. javacc jjtree 写法 以及 jj写法 基本语法 以及应用
  16. C语言学习笔记《带你学C带你飞》P41-P61
  17. 切蛋糕java题,【算法•日更•第六期】头脑风暴:洛谷P1528 切蛋糕题解
  18. msfvenom生成木马的简单利用
  19. 麻将番型计算(二人麻将)
  20. osgEarth示例分析——osgearth_annotation

热门文章

  1. numpy教程:数学函数和基本统计函数
  2. java第七章jdbc课后简答题_Java进阶之JDBC面试题(7)
  3. 怎样调整input框背景颜色_还在用百度搜索PPT背景图?7个高大上的图片网站,个个都是高清免费无版权!...
  4. android 打包问题,Android离线打包常见问题
  5. 蓝桥杯2017年第八届C/C++省赛C组第八题-九宫幻方
  6. 力扣-1232 缀点成线
  7. 使用 Multipath TCP 为 iOS 创建备份连接(转)
  8. 开源协议的几种类型认识
  9. Android Application基本组成部分
  10. DataAdapter对象填充数据集