bzoj 3224: Tyvj 1728 普通平衡树 替罪羊树
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
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 普通平衡树 替罪羊树的更多相关文章
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 7390 Solved: 3122 [Submit][S ...
- BZOJ - 3224 Tyvj 1728 普通平衡树 (treap/树状数组)
题目链接 treap及树状数组模板题. treap版: #include<bits/stdc++.h> using namespace std; typedef long long ll; ...
- BZOJ 3224: Tyvj 1728 普通平衡树 or 洛谷 P3369 【模板】普通平衡树-Splay树模板题
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 22483 Solved: 10130[Submit][S ...
- BZOJ 3224: Tyvj 1728 普通平衡树
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9629 Solved: 4091[Submit][Sta ...
- BZOJ 3224: Tyvj 1728 普通平衡树 treap
3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...
- BZOJ 3224: Tyvj 1728 普通平衡树 vector
3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...
- BZOJ 3224: Tyvj 1728 普通平衡树(BST)
treap,算是模板题了...我中间还一次交错题... -------------------------------------------------------------------- #in ...
- bzoj 3224: Tyvj 1728 普通平衡树 && loj 104 普通平衡树 (splay树)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 思路: splay树模板题: 推荐博客:https://blog.csdn.ne ...
- BZOJ 3224 Tyvj 1728 普通平衡树模板
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 题目大意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以 ...
随机推荐
- 【solr基础教程之一】Solr相关知识点串讲
Solr是Apache Lucene的一个子项目.Lucene为全文搜索功能提供了完备的API,但它只作为一个API库存在,而不能直接用于搜索.因此,Solr基于Lucene构建了一个完 ...
- Backward Digit Sums(POJ 3187)
Backward Digit Sums Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5495 Accepted: 31 ...
- android R 文件 丢失的处理 如何重新生成
很多时候我们会遇到工程中的R.java文件丢失,必要急,修复很简单. 方法:右击你的工程(项目)——>Android Tools——>Fix Project Properties 即可. ...
- USB系列之五:用汇编实现的一些USB功能
前面的USB系列一至四,实现了我们需要的一些USB功能,但都是用C语言的32位代码,之后我们插进了三篇关于DOS下设备驱动程序的文章,我们现在应该清楚,当我们要在DOS下写一个U盘的驱动时,最好使用汇 ...
- scheme一页纸教程
这是一个大学教授写的,非常好,原文:http://classes.soe.ucsc.edu/cmps112/Spring03/languages/scheme/SchemeTutorialA.html ...
- 定时任务:Java中Timer和TimerTask的使用
java.util.Timer定时器,实际上是个线程,定时调度所拥有的TimerTasks. 一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内,TimerT ...
- Longest Substring Without Repeating Characters 解答
Question Given a string, find the length of the longest substring without repeating characters. For ...
- J2EE之ANT
Ant是一种基于Java的build工具.由一些内置任务组成.这些任务用于编译和运行java应用.创建文档.文件和文件夹的操作. 理论上来说.它有些类似于(Unix)C中的make ,但没有make的 ...
- iOS开发系列--打造自己的“美图秀秀”
概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益于它强大的开发框架.今天我们将围绕iOS中两大图形.图像绘图框架进行介绍:Quartz 2D绘制2D图形和Co ...
- excel笔记
提取单元格中的数字部分 =MID(LOOKUP(1,-(1&MID(A1,MIN(FIND({0;1;2;3;4;5;6;7;8;9},A1&1/17)),ROW($1:$15)))) ...