Problem 普通平衡树

Solution

本题是裸的二叉平衡树。有很多种方法可以实现。这里打的是替罪羊树模板。 
此题极其恶心。 
前驱后继模块需要利用到rank模块来换一种思路求。 
很多细节的地方容易炸。我拿数据调了很久才A。 
(delt()删除模块其实是不需要重建的,不影响时间复杂度) 
替罪羊树具体详见此篇知乎:替罪羊树

AC Code

 #include "iostream"
#include "cstdio"
#define alpha 0.7
using namespace std;
struct ScapeGoatTree{
int lc,rc,n,w,s,fa;
}a[];
struct REbuild{
int n,w;
}d[];
void rebuild(int p);
int tot=,tott=,top=,h[],n,T,X,root;
int check(int p){
if(a[p].w==)return ;
if ((a[a[p].lc].s+a[a[p].lc].w>=double(alpha*(a[p].w+a[p].s)))||
(a[a[p].rc].s+a[a[p].rc].w>=double(alpha*(a[p].w+a[p].s))))return ;
return ;
}
int getN(int x){
int now=root;
while(a[now].n!=x&&a[now].s!=){
if(a[now].n>=x)now=a[now].lc;
else now=a[now].rc;
}
return now;
}
void insr(int x,bool rb){
if(root==){
root=;
a[].n=x;
a[].w++;
return;
}
int now=root;
while(a[now].s!=){
if(x==a[now].n){
a[now].w++;
return;
}
if(x>a[now].n&&a[now].rc==)break;
if(x<a[now].n&&a[now].lc==)break;
a[now].s++;
if(x>a[now].n)now=a[now].rc;
else if(x<a[now].n)now=a[now].lc;
} if(x==a[now].n){
a[now].w++;
return;
}
a[now].s++;
int tmp=now;
if(x>a[now].n)now=a[now].rc=++tot;
else if(x<a[now].n)now=a[now].lc=++tot;
a[now].w++;
a[now].n=x;
if(tmp!=now)a[now].fa=tmp;
int chk=;
while(now!=root){
now=a[now].fa;
if(check(now))chk=now;
}
if(rb)rebuild(chk);
}
int getnewp(){
if(top>){
top--;
return h[top+];
}
else return ++tot;
}
void dfs(int p){
h[++top]=p;
if(a[p].lc!=)dfs(a[p].lc);
if(a[p].w!=)d[++tott].n=a[p].n,
d[tott].w=a[p].w;
a[p].s=;
if(a[p].rc!=)dfs(a[p].rc);
}
void make(int l,int r,int p,int fa){
int mid=(l+r)/;
a[p].fa=fa;
a[p].w=d[mid].w;
a[p].n=d[mid].n;
if(mid->=l)a[p].lc=getnewp(),make(l,mid-,a[p].lc,p);else a[p].lc=;
if(mid+<=r)a[p].rc=getnewp(),make(mid+,r,a[p].rc,p);else a[p].rc=;
a[p].s=a[a[p].lc].w+a[a[p].lc].s+a[a[p].rc].w+a[a[p].rc].s;
}
void rebuild(int p){
if(p==)return;
tott=;
dfs(p);
int now=getnewp();
a[now].fa=a[p].fa;
if(p==root)root=now;
int mid=(+tott)/;
if(d[mid].n>a[a[p].fa].n)a[a[p].fa].rc=now;
else a[a[p].fa].lc=now;
make(,tott,now,a[p].fa);
}
void delt(int p,bool rb){
a[p].w--;
int chk=;
while(p!=root){
p=a[p].fa;
a[p].s--;
if(check(p))chk=p;
}
// if(rb)rebuild(chk);
}
int XgetRk(int x);
int RkgetX(int x);
int suc(int x){
insr(x+,);
int tmp=XgetRk(x+),nx=getN(x+);
delt(nx,);
return RkgetX(tmp);
}
int pre(int x){
insr(x,);
int tmp=XgetRk(x);
delt(getN(x),);
return RkgetX(tmp-);
}
int XgetRk(int x){
int p=getN(x),ans;
ans=a[a[p].lc].s+a[a[p].lc].w;
while(p!=root){
if(a[a[p].fa].rc==p)ans+=a[a[a[p].fa].lc].s+a[a[a[p].fa].lc].w+a[a[p].fa].w;
p=a[p].fa;
}
return ans+;
}
int RkgetX(int x){
int now=root;
while(true){
int lcS=a[a[now].lc].s+a[a[now].lc].w;
if(x<=lcS)now=a[now].lc;
else if(x>lcS&&x<=a[now].w+lcS)return a[now].n;
else x-=lcS+a[now].w,now=a[now].rc;
if(x==)return a[now].fa;
}
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
if(i%==){
int ttott;
ttott++;
}
scanf("%d%d",&T,&X);
if(T==)insr(X,);
else if(T==)delt(getN(X),);
else if(T==)printf("%d\n",XgetRk(X));
else if(T==)printf("%d\n",RkgetX(X));
else if(T==)printf("%d\n",pre(X));
else if(T==)printf("%d\n",suc(X));
}
}

[TYVJ1728/BZOJ3224]普通平衡树-替罪羊树的更多相关文章

  1. Luogu 3369 / BZOJ 3224 - 普通平衡树 - [替罪羊树]

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 https://www.luogu.org/problemnew/show/P3 ...

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

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

  3. bzoj2827: 千山鸟飞绝 平衡树 替罪羊树 蜜汁标记

    这道题首先可以看出坐标没有什么意义离散掉就好了. 然后你就会发现你要每次都更改坐标,而一旦更改受影响的是坐标里的所有数,要是一个一个的改,会不可描述. 所以换个视角,我们要找的是某只鸟所到每个坐标时遇 ...

  4. bzoj 3224: Tyvj 1728 普通平衡树 替罪羊树

    题目链接 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的 ...

  5. [luogu3369]普通平衡树(替罪羊树模板)

    解题关键:由于需要根据平衡进行重建,所以不能进行去重,否则无法保证平衡性. #include<cstdio> #include<cstring> #include<alg ...

  6. Bzoj3224 / Tyvj 1728 普通替罪羊树

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 12015  Solved: 5136 Description 您需要写一种数据结构(可参考题目标题), ...

  7. 【替罪羊树】bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树

    [替罪羊树]bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树 bzoj 洛谷 cogs 先长点芝士 替罪羊树也是一种很好写的平衡树qwq..替罪 ...

  8. 替罪羊树—BZOJ3224: Tyvj 1728 普通平衡树

    冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ). 先是打了一下想学好久的替罪羊树. 替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树. 调试小结: 1.删除操作分两类情况:如果某 ...

  9. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

随机推荐

  1. Notification的基本用法以及使用RemoteView实现自定义布局

    Notification的作用 Notification是一种全局效果的通知,在系统的通知栏中显示.既然作为通知,其基本作用有: 显示接收到短消息.即时信息等 显示客户端的推送(广告.优惠.新闻等) ...

  2. 做一枚精致的程序猿,Fighting!

    这几天我和我们的团队正在做一个公司管理系统的项目,团队分工根据成员的水平高低来分工,这样看似公平,但其实不公平,如此这样一来,那些水平稍不如别人的成员就没有发展的机会?那么问题来了,对于水平稍逊色的程 ...

  3. 每篇半小时1天入门MongoDB——2.MongoDB环境变量配置和Shell操作

    上一篇:每篇半小时1天入门MongoDB——1.MongoDB介绍和安装 配置环境变量 Win10系统为例 右键单击“此电脑”——属性——高级系统设置——高级——环境变量,添加C:\Program F ...

  4. Django中的枚举类型

    一.枚举类型示例 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等.Python 的原生类型(Built-in types)里并没有专门的枚举类型 ...

  5. Akka(7): FSM:通过状态变化来转换运算行为

    在上篇讨论里我们提到了become/unbecome.由于它们本质上是堆栈操作,所以只能在较少的状态切换下才能保证堆栈操作的协调及维持程序的清晰逻辑.对于比较复杂的程序流程,Akka提供了FSM:一种 ...

  6. js实现整数转化为小数

    toFixed 方法 返回一个字符串,代表一个以定点表示法表示的数字. number .toFixed(i) 参数 bumber 必选项.一个 Number 对象. i 可选项.小数点 后的数字位数. ...

  7. C语言和go语言之间的交互

    一.go代码中使用C代码 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import "C" 即可在go代码中使用C函数 代码示例: go代码:tes ...

  8. WCF学习——构建一个简单的WCF应用(二)

    我们接着上一篇文章进行讲解 http://www.cnblogs.com/songjianhui/p/7060698.html 一:客户端通过添加引用调用服务 WCF应用服务被成功寄宿后,WCF服务应 ...

  9. salesforce零基础学习(七十四)apex:actionRegion以及apex:actionSupport浅谈

    我们在开发中,很难会遇见不提交表单的情况.常用的apex:commandButton,apex:commandLink,apex:actionFunction,apex:actionSupport.他 ...

  10. Maven转化为Dynamic Web Module

    如今Maven仍然是最常用的项目管理工具,若要将Java Web项目使用Maven进行管理,则首先需要新建Maven项目,然后将其转化为web项目. 在项目右键选择properties,然后点击左侧P ...