题目链接

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
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插件编写

    /*(function($) { $.fn.accordion = function(options) { var settings = $.extend({}, {open: false}, opt ...

  2. web 前端 shopnc项目 首页分类一开始做前端,我是拒绝的

    看图别说话 经过几小时的折腾 主要还是靠耐心

  3. 黑马程序员 1、C语言32个关键字整理分类

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ C语言一共有32个关键字 一.数据类型关键字(共20个) A.基本数据类型(5个)void :声明 ...

  4. Histats安装Counter网站计数器 - Blog透视镜

    Histats提供十分多样性的Counter网站计数器,可以依照你个人的喜好与需求,选择适合的Counter网站计数器,也可以针对同一网站,安装多个Counter网站计数器,作法其实比注册账号时更简单 ...

  5. 十一、外观(Facade)模式--结构模式(Structural Pattern)

    外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式.门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行. 门面模式提供一个高层次 ...

  6. Application.HookMainWindow完全替代了原来的窗口过程(但是好像也会继续传递)

    unit HookMain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialo ...

  7. Socket也有专门的Unicode版本

    https://www.chilkatsoft.com/refdoc/wcppCkSocketWRef.html https://www.chilkatsoft.com/refdoc/vcCkSock ...

  8. C语言的本质(34)——静态库

    库是一种软件组件技术,库里面封装了数据和函数. 库的使用可以使程序模块化. Windows系统包括静态链接库(.lib文件)和动态链接库(.dll文件). Linux通常把库文件存放在/usr/lib ...

  9. HBase 3、HBase练习题

    1.建立学生和课程表 要求:学生可以选择多个课程,每个课程可以被多个学生选择. 查询某个学生所选的所有课程列表 查询某个课程,的学生列表 学生可以修改所选的课程 方案:学生与课程之间是多对多关系,那可 ...

  10. android笔试题集2

    1.请谈一下Android系统的架构.答:Android系统采用了分层架构,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和linux核心层. 2.谈谈android大众常用的五种布局.答 ...