题目链接

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

这题用替罪羊树过的。

替罪羊树, 其实就是一种很暴力的方法。 如果一个节点的左子树节点个数大于它节点个数*alpha或者右子树节点个数大于节点个数*alpha。 那么就将这个节点及它的子树重构。

重构非常暴力, 就是把它变成一个序列, 然后不停的找中点。 相当于将之前的不平衡的二叉树变成了一个完全二叉树。

在删除时, 并不是直接删除, 而是将这个节点打个标记。

代码中, sz是有效节点的个数, 而cover是总结点的个数。 在删除的时候, 如果根节点的sz < alpha*cover。 那么就将整棵树重构。

#include <bits/stdc++.h>

using namespace std;
#define MAXN 100010
const double alpha = 0.75;
struct node
{
int sz, cover, val;
bool exist;
node* ch[];
node()
{
ch[] = ch[] = NULL;
exist = false;
sz = cover = ;
}
node(int val):val(val)
{
sz = cover = ;
exist = true;
ch[] = ch[] = NULL;
}
void pushUp(node* tmp)
{
sz += tmp->sz;
cover += tmp->cover;
}
bool isBad()
{
int tmpL = ch[]?ch[]->cover:;
int tmpR = ch[]?ch[]->cover:;
if(tmpL > cover * alpha + ||
tmpR > cover * alpha + )
return true;
return false;
}
};
node* root = NULL;
void add(node*& p, int val, node** flag)
{
if(p == NULL) {
p = new node(val);
return ;
}
p->sz++;
p->cover++;
add(p->ch[val >= p->val], val, flag);
if(p->isBad()) {
flag = &p;
}
}
void Erase(node* p, int k)
{
int x = p->ch[]?p->ch[]->sz:;
int tmp = x + (int)(p->exist);
p->sz--;
if(p->exist && tmp == k) {
p->exist = false;
return ;
}
if(k <= tmp) {
Erase(p->ch[], k);
} else {
Erase(p->ch[], k - tmp);
}
}
void traval(node*& p, vector<node*>& v)
{
if(p == NULL)
return ;
traval(p->ch[], v);
if(p->exist) {
v.push_back(p);
}
traval(p->ch[], v);
}
void divide(node*& p, vector<node*>& v, int l, int r)
{
if(l > r)
return ;
if(p == NULL)
p = new node();
int mid = l + r >> ;
p = v[mid];
divide(p->ch[], v, l, mid - );
divide(p->ch[], v, mid + , r);
if(p->ch[])
p->pushUp(p->ch[]);
if(p->ch[])
p->pushUp(p->ch[]);
if(p->exist)
p->sz++;
p->cover++;
}
void rebuild(node*& p)
{
vector <node*> v;
traval(p, v);
divide(p, v, , v.size()-);
}
int Rank(node*& p, int x)
{
if(p == NULL)
return ;
int ret = ;
if(p->val >= x) {
ret = Rank(p->ch[], x);
} else {
int tmp = (p->ch[])?p->ch[]->sz:;
ret = tmp + (int)p->exist;
ret += Rank(p->ch[], x);
}
return ret;
}
int Kth(node*& p, int k)
{
if(p == NULL)
return ;
int tmp = (p->ch[])?p->ch[]->sz:;
if(p->exist && tmp + == k)
return p->val;
if(tmp >= k) {
return Kth(p->ch[], k);
} else {
return Kth(p->ch[], k - tmp - p->exist);
}
}
void Insert(int val)
{
node** flag = NULL;
add(root, val, flag);
if(flag != NULL) {
rebuild(*flag);
}
}
void Erase(int k)
{
Erase(root, k);
if((double)root->sz < (double)(alpha*root->cover))
rebuild(root);
}
int main()
{
int n, sign, x;
cin>>n;
while(n--) {
scanf("%d%d", &sign, &x);
switch(sign) {
case : Insert(x);break;
case : Erase(root, Rank(root, x));break;
case : printf("%d\n", Rank(root, x));break;
case : printf("%d\n", Kth(root, x));break;
case : printf("%d\n", Kth(root, Rank(root, x) - ));break;
case : printf("%d\n", Kth(root, Rank(root, x + )));break;
}
}
return ;
}

bzoj 3224: Tyvj 1728 普通平衡树 替罪羊树的更多相关文章

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

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

  2. BZOJ - 3224 Tyvj 1728 普通平衡树 (treap/树状数组)

    题目链接 treap及树状数组模板题. treap版: #include<bits/stdc++.h> using namespace std; typedef long long ll; ...

  3. BZOJ 3224: Tyvj 1728 普通平衡树 or 洛谷 P3369 【模板】普通平衡树-Splay树模板题

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 22483  Solved: 10130[Submit][S ...

  4. BZOJ 3224: Tyvj 1728 普通平衡树

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9629  Solved: 4091[Submit][Sta ...

  5. BZOJ 3224: Tyvj 1728 普通平衡树 treap

    3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...

  6. BZOJ 3224: Tyvj 1728 普通平衡树 vector

    3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...

  7. BZOJ 3224: Tyvj 1728 普通平衡树(BST)

    treap,算是模板题了...我中间还一次交错题... -------------------------------------------------------------------- #in ...

  8. bzoj 3224: Tyvj 1728 普通平衡树 && loj 104 普通平衡树 (splay树)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 思路: splay树模板题: 推荐博客:https://blog.csdn.ne ...

  9. BZOJ 3224 Tyvj 1728 普通平衡树模板

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 题目大意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以 ...

随机推荐

  1. 分享几个实用的jquery工具函数

    1.$.browser对象属性 属性列表 说明  webkit webkit相关浏览器则返回true,否则返回false,如google,傲游.  mozilla mozilla相关浏览器则返回tru ...

  2. linux下安装pdf

    官方下载地址:http://www.foxitsoftware.cn/downloads/ 问题:下载官方包以后解压,双击不能打开,也没有任何提示. 用teminal 来打开foxitreader,t ...

  3. 分西瓜(DFS)

    描述今天是阴历七月初五,acm队员zb的生日.zb正在和C小加.never在武汉集训.他想给这两位兄弟买点什么庆祝生日,经过调查,zb发现C小加和never都很喜欢吃西瓜,而且一吃就是一堆的那种,zb ...

  4. 关于C语言静态链接的个人理解,欢迎指正

    摘要:本篇主要介绍在静态链接中多个文件合并.地址确定.符号解析和重定位相关问题,以GCC编译器为例.     首先,链接器链接多个文件时,采用何种方式合并为一个文件?方式一,按序叠加,即多个文件依次叠 ...

  5. ES6新特性-------解构、参数、模块和记号(续)

    六.解构 解构提供了一个方便的地从对象或数组中提取数据的方法,请看下面的例子: //ES6 let [x,y]=[1,2];//x=1,y=2 //ES5 var arr=[1,2]; var x=a ...

  6. mysql-protocol中对编码长度整数型的规则

    固定长度整型数值在mysql 协议中的应用之一就是affected row :这个要根据首字节来判断 1.如果首字节小于251;那么首字节就是它要表示的数值. 2.如果首字节等于251;那么它表示的就 ...

  7. KL25用SPI操作nor flash

    KL25的SPI连接一个nor flash.该flash型号为FM25F04,支持SPI的模式0和模式3,要求高位先发送,在上升沿采集数据. 通常,SPI有4种模式,取决于CPOL与CPHA如何配置. ...

  8. javascript之数组

    一.定义数组. 定义数组有两个方法: 1.var arr1 = []; //定义一个空数组 2.var arr2 = [1,2,3,"str1","str2"] ...

  9. 【转】 linux内核移植和网卡驱动(二)

    原文网址:http://blog.chinaunix.net/uid-29589379-id-4708911.html 一,内核移植步骤: 1, 修改顶层目录下的Makefile ARCH       ...

  10. Path Sum 解答

    Question Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that addi ...