#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define alpha 0.8
#define maxn 2000001
#define ri register
#define il inline
using namespace std;
struct scapegoat{
int son[2], val, valid, total;//valid(有效的)未被删除的子树的点数 total(总数)子树总点数
bool exist;//是否要被删除 exist(存在)1表示未被删除 0表示被删除
}e[maxn];
int memory[maxn]; //内存池
int cur[maxn]; //拍扁的时候用的内存空间
int root, pool, poi, cnt, to_rebuild;
il bool isbad(int now)
{
if((double)e[now].valid*alpha <= (double)max(e[e[now].son[0]].valid, e[e[now].son[1]].valid)) return true;
return false;
}
void dfs(int now) // 中序遍历,找出要被拍扁的节点的编号
{
if(!now) return;
dfs(e[now].son[0]);
if(e[now].exist) cur[++poi] = now;
else memory[++pool] = now;
dfs(e[now].son[1]);
}
void build(int l, int r, int &now) //你建树值要跟着变的...now当然加&了...
{
int mid = l+r>>1;//其实建树的序列已经按顺序保存在cur里了,你只需要改变父子关系就行
now = cur[mid];//cur里存的是编号.把中间的元素取出来,中间元素的编号为now.
if(l == r)//只造一个节点..?
{
e[now].son[0] = e[now].son[1] = 0;
e[now].total = e[now].valid = 1;
return;
}
if(l < mid) build(l,mid-1,e[now].son[0]);//到mid-1是因为mid已经建完了
else e[now].son[0] = 0;
build(mid+1,r,e[now].son[1]);//左右递归建树
e[now].total = e[e[now].son[0]].total + e[e[now].son[1]].total + 1;//更新节点信息
e[now].valid = e[e[now].son[0]].valid + e[e[now].son[1]].valid + 1;
}
il void rebuild(int &now)
{
poi = 0;//别忘了你重建的子树要从头开始算啊,不清零..就听取WA声一片
dfs(now);//中序遍历一遍
if(poi) build(1,poi,now);
else now = 0;
}
il int find_rank(int k)//寻找k的排名
{
int now = root;
int ans = 1;
while(now)
{
if(e[now].val >= k) now = e[now].son[0];
else
{
ans += e[e[now].son[0]].valid + e[now].exist;//+e[now].exist是因为我相同大小的节点虽然放在一起,但是我不知道我这个节点上相同的我是不是还存在啊..所以我得单独加我..至于valid是除我以外的子树大小。
now = e[now].son[1];
}
}
return ans;
}
il int find_kth(int k)
{
int now = root;
while(now)
{
if(e[now].exist&&e[e[now].son[0]].valid+1 == k) return e[now].val;
else if(e[e[now].son[0]].valid >= k) now = e[now].son[0];
else
{
k -= e[e[now].son[0]].valid + e[now].exist;
now = e[now].son[1];
}
}
}
void insert(int &now, int val)
{
if(!now)//找到一个插入的位置
{
now = memory[pool--]; e[now].val = val;
e[now].exist = e[now].total = e[now].valid = 1;
e[now].son[0] = e[now].son[1] = 0;
return;
}
e[now].total++, e[now].valid++;//一边向下一边更新,这点与spaly不同
if(e[now].val >= val) insert(e[now].son[0], val);
else insert(e[now].son[1], val);
if(!isbad(now))
{
if(to_rebuild)
{
if(e[now].son[0] == to_rebuild) rebuild(e[now].son[0]);
else rebuild(e[now].son[1]);
to_rebuild = 0;
}
}
else to_rebuild = now;
}
il void delete_pos(int &now, int tar) //target(目标)
{
if(e[now].exist&&e[e[now].son[0]].valid+ 1 == tar)//删除位置为tar的..
{
e[now].exist = 0; e[now].valid--; return;
}
e[now].valid--;
if(e[e[now].son[0]].valid + e[now].exist >= tar) delete_pos(e[now].son[0], tar);
else delete_pos(e[now].son[1],tar-e[e[now].son[0]].valid-e[now].exist);
}
il void delete_val(int tar)
{
delete_pos(root, find_rank(tar));
if((double)e[root].total*alpha > e[root].valid) rebuild(root);
}
int main()
{
int opt, x, m;
for(int i = 2000000; i >= 1; i--) memory[++pool] = i;
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&opt,&x);
if(opt == 1) {insert(root, x);}
if(opt == 2) {delete_val(x);}
if(opt == 3) {printf("%d\n",find_rank(x));}
if(opt == 4) {printf("%d\n",find_kth(x));}
if(opt == 5) {printf("%d\n",find_kth(find_rank(x)-1));}
if(opt == 6) {printf("%d\n",find_kth(find_rank(x+1)));}
}
//哇这太恐怖了我的替罪羊树他还能查没有插入的节点的排名...(好像是对于没插入过的节点会假装插进去了查询一个排名..但下次操作不会当做真插入了来做)
return 0;
}

【luogu P3369 【模板】普通平衡树(Treap/SBT)】 模板 Scapegoat Tree的更多相关文章

  1. luoguP3369[模板]普通平衡树(Treap/SBT) 题解

    链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...

  2. BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7390  Solved: 3122 [Submit][S ...

  3. 平衡树 替罪羊树(Scapegoat Tree)

    替罪羊树(Scapegoat Tree) 入门模板题 洛谷oj P3369 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入xx数 删除xx数(若有多个相同 ...

  4. 【模板】平衡树——Treap和Splay

    二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...

  5. [luogu P3369]【模板】普通平衡树(Treap/SBT)

    [luogu P3369][模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删 ...

  6. 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...

  7. 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...

  8. 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 近几天闲来无事...就把各种平衡树都写了一下... 下面是红黑树(Red Black Tree) 喜闻乐见拿到了luo ...

  9. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

  10. AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

    [模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...

随机推荐

  1. 在Spark shell中基于Alluxio进行wordcount交互式分析

    Spark是一个分布式内存计算框架,可部署在YARN或者MESOS管理的分布式系统中(Fully Distributed),也可以以Pseudo Distributed方式部署在单个机器上面,还可以以 ...

  2. 024-cxf.xml配置文件模板

    版本一 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://ww ...

  3. ife task0003学习笔记(四):JavaScript构造函数

    JavaScript创建对象主要是3种方法:工厂模式.构造函数模式.原型模式.其实对于构造函数的概念,我们并不陌生.在之前学习c++语言的时候,也有提到过构造函数的概念.除了创建对象,构造函数(con ...

  4. 初识backbone.js

    backbone,英文意思是:勇气, 脊骨,但是在程序里面,尤其是在backbone后面加上后缀js之后,它就变成了一个框架,一个js库. backbone.js,不知道作者是以什么样的目的来对其命名 ...

  5. python网络编程——简单例子

    客户端(client.py) import socket import sys port = 70 host = sys.argv[1] filename = sys.argv[2] s = sock ...

  6. 【卷土重来之C#学习笔记】(三) 类型 存储和变量

    .c#程序是一组类型声明 ※C#程序或DLL的源代码是一组一种或多种类型声明 ※对于可执行程序,类型声明必须有一个包含Main方法类 ※命名空间是一种把相关的类型声明分组并命名的方法.既然程序是一组相 ...

  7. CF 305A——Strange Addition——————【暴力加技巧】

    A. Strange Addition time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  8. 深入理解JavaScript系列(9):根本没有“JSON对象”这回事!

    前言 写这篇文章的目的是经常看到开发人员说:把字符串转化为JSON对象,把JSON对象转化成字符串等类似的话题,所以把之前收藏的一篇老外的文章整理翻译了一下,供大家讨论,如有错误,请大家指出,多谢. ...

  9. spring+springmvc+hibernate整合遇到的问题

    spring+springmvc+hibernate整合遇到的问题2016年10月20日 23:24:03 守望dfdfdf 阅读数:702 标签: ssh学习经历的异常exception异常框架更多 ...

  10. C语言入门(一)环境搭建

    1. 下载Code::Blocks(源文本编辑器) 2. 下载编译器MinGW(或者下载好自带编译器的codeblocks) http://jingyan.baidu.com/article/c843 ...