替罪羊树及其模板

替罪羊树 模板 替罪羊树在此!!!(你说什么?为什么要写替罪羊树,请看这篇博客,貌似我之前的解释有1篇博文吧,希望你有耐心,慢慢看,网址:http://blog.csdn.net/cnyali_ljf/article/details/52613275) 好了,替罪羊树是什么我也不知道(其实我知道),但是我又没有那么大的耐心慢慢写,今天就只写一个模板给你们看看吧,如果有解释的话我把网址再贴给你们: 写得真累, 阅读详情
替罪羊是我目前会的最快的平衡树。口说无凭,这篇文章就是证据。
替罪羊树是一种重量平衡树。我们知道大部分平衡树都是要旋转的,只有非旋Treap和替罪羊不用旋转。替罪羊的思路很简单,就是当我们发现子树不平衡之后,就重构一遍。

替罪羊重构:
重构是替罪羊的精华,替罪羊的重构其实很暴力,比如我们要重构x的子树,就先将x的子树里的点全部回收起来。然后重构一棵二叉树,每次选节点的时候都选当前序列的中点。这样二分建树即可。
回收点:每次回收点时都优先向左边的点回收,然后再回收右边,这样就可以保证回收成的数组单调递增(不下降)。
 void recycle(int k){
        if(!k) return;
        recycle(son[k][0]);
        cur[++sum]=k;
        recycle(son[k][1]);
    }
重构:直接二分重构
int build(int l,int r){
        if(l>r) return 0;
        int mid=(l+r)>>1,id=cur[mid];
        fa[son[id][0]=build(l,mid-1)]=id;
        fa[son[id][1]=build(mid+1,r)]=id;
        siz[id]=siz[son[id][0]]+siz[son[id][1]]+1;
        return id;
    }
    void rebuild(int k){
        sum=0;recycle(k);  //回收
        int f=fa[k],d=(son[f][1]==k),id=build(1,sum);  //build递归重构
        fa[son[f][d]=id]=f;
        if(k==root) root=id;
    }

插入:
替罪羊的插入类似于其它的平衡树,但是在插入之后我们要往上回溯它的祖先,然后找它的祖先中深度最浅的。然后重构这个点的子树。
void insert(int x){
        if(!root){val[root=++sz]=x,siz[root]=1,fa[root]=0;return;}
        int tmp=root;
        while(1){
            siz[tmp]++;
            int f=tmp,d=(x>=val[tmp]);tmp=son[tmp][d];
            if(!tmp){
                siz[++sz]=1,val[sz]=x,fa[sz]=f,son[f][d]=sz;
                break;
            }
        }
        int flag=0;
        for(int i=sz;i;i=fa[i]) if(!isbad(i)) flag=i;
        if(flag) rebuild(flag);
    }

删除:
替罪羊的删除其实不同于其他的平衡树,我们可以直接打一个标记,标记这个点已经被删除了,但是这个点实际上是存在的。然后我们操作的时候就不管已经标记过的点。然后如果标记过的点太多了,就直接暴力重构整棵树,并且回收的时候不回收标记的节点。这样就完成了删除。
我打的并不是这个版本,我打的还是类似于splay的删除。直接将点x赋值为它的前驱,然后再删掉这个前驱即可。
int getpl(int x){   //找位置
        int tmp=root;
        while(tmp){
            if(x==val[tmp]) return tmp;
            int d=(x>=val[tmp]);
            tmp=son[tmp][d];
        }
        return tmp;
    }
    void erase(int k){
        if(son[k][0]&&son[k][1]){  //将点赋值为它前驱
            int tmp=son[k][0];
            while(son[tmp][1]) tmp=son[tmp][1];
            val[k]=val[tmp];k=tmp;
        }
        int s=son[k][0]?son[k][0]:son[k][1],f=fa[k],d=(son[f][1]==k);
        son[f][d]=s;fa[s]=f;
        for(int i=f;i;i=fa[i]) siz[i]--;
        if(root==k) root=s;
    }

其它的操作类似于普通平衡树。
模板:BZOJ3224

#include<bits/stdc++.h>
#define MAXN 800005
#define INF 2e9
using namespace std;
int read(){
    char c;int x=0,y=1;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
    if(c=='-') y=-1;else x=c-'0';while(c=getchar(),c>='0'&&c<='9')
    x=x*10+c-'0';return x*y;
}
const double alpha=0.7;
int n,sz,root;
struct Scapegoat{
    int sum;
    int son[MAXN][2],siz[MAXN],val[MAXN],ct[MAXN],cur[MAXN],fa[MAXN];
    int isbad(int x){
        return (double)siz[x]*alpha>max(siz[son[x][0]],siz[son[x][1]]);
    }
    void recycle(int k){
        if(!k) return;
        recycle(son[k][0]);
        cur[++sum]=k;
        recycle(son[k][1]);
    }
    int build(int l,int r){
        if(l>r) return 0;
        int mid=(l+r)>>1,id=cur[mid];
        fa[son[id][0]=build(l,mid-1)]=id;
        fa[son[id][1]=build(mid+1,r)]=id;
        siz[id]=siz[son[id][0]]+siz[son[id][1]]+1;
        return id;
    }
    void rebuild(int k){
        sum=0;recycle(k);
        int f=fa[k],d=(son[f][1]==k),id=build(1,sum);
        fa[son[f][d]=id]=f;
        if(k==root) root=id;
    }
    void insert(int x){
        if(!root){val[root=++sz]=x,siz[root]=1,fa[root]=0;return;}
        int tmp=root;
        while(1){
            siz[tmp]++;
            int f=tmp,d=(x>=val[tmp]);tmp=son[tmp][d];
            if(!tmp){
                siz[++sz]=1,val[sz]=x,fa[sz]=f,son[f][d]=sz;
                break;
            }
        }
        int flag=0;
        for(int i=sz;i;i=fa[i]) if(!isbad(i)) flag=i;
        if(flag) rebuild(flag);
    }
    int getpl(int x){
        int tmp=root;
        while(tmp){
            if(x==val[tmp]) return tmp;
            int d=(x>=val[tmp]);
            tmp=son[tmp][d];
        }
        return tmp;
    }
    void erase(int k){
        if(son[k][0]&&son[k][1]){
            int tmp=son[k][0];
            while(son[tmp][1]) tmp=son[tmp][1];
            val[k]=val[tmp];k=tmp;
        }
        int s=son[k][0]?son[k][0]:son[k][1],f=fa[k],d=(son[f][1]==k);
        son[f][d]=s;fa[s]=f;
        for(int i=f;i;i=fa[i]) siz[i]--;
        if(root==k) root=s;
    }
    int findRANK(int x){
        int tmp=root,res=0;
        while(tmp){
            if(x<=val[tmp]) tmp=son[tmp][0];
            else res+=siz[son[tmp][0]]+1,tmp=son[tmp][1];
        }
        return res+1;
    }
    int findNUM(int x){
        int tmp=root;
        while(tmp){
            if(x<=siz[son[tmp][0]]){
                tmp=son[tmp][0];continue;
            }
            x-=siz[son[tmp][0]];
            if(x==1) return val[tmp];x--;
            tmp=son[tmp][1];
        }
    }
    int findPRE(int x){
        int ret=-INF,tmp=root;
        while(tmp){
            if(val[tmp]<x) ret=max(ret,val[tmp]),tmp=son[tmp][1];
            else tmp=son[tmp][0];
        }
        return ret;
    }
    int findSUF(int x){
        int ret=INF,tmp=root;
        while(tmp){
            if(val[tmp]>x) ret=min(ret,val[tmp]),tmp=son[tmp][0];
            else tmp=son[tmp][1];
        }
        return ret;
    }
}T;
int main()
{
    n=read();
    for(int i=1;i<=n;i++){
        int type=read(),x=read();
        if(type==1) T.insert(x);
        if(type==2){int p=T.getpl(x);if(p) T.erase(p);}
        if(type==3) printf("%d\n",T.findRANK(x));
        if(type==4) printf("%d\n",T.findNUM(x));
        if(type==5) printf("%d\n",T.findPRE(x));
        if(type==6) printf("%d\n",T.findSUF(x));
    }
    return 0;
}
二叉树——替罪羊树.ppt 1 引入替罪羊树的目的 2 替罪羊树的定义 3 替罪羊树的基本操作: 插入 删除 查询 立即下载

相关推荐

[PayPal报错]为遵守国际法规,这笔交易已被拒绝。

PayPal报错解决:为遵守国际法规,这笔交易已被拒绝。

qq_39906413的博客 1万+

【替罪羊树及其应用】替罪羊树总结

替罪羊树是重量平衡树的一种,对于简单的平衡树应用,特别是维护的信息无法快速合并时,替罪羊树是个出色的选择。它的代码比较好理解,思想简单而暴力:对于一个节点,当左右子树的节点数量不平均时,我们就把它重构一遍。下面,我们重点阐述一下重构操作。 【基本操作】 1.拍扁重构操作: 当我们发现深度最浅的一个节点的子树不平衡时,我们从这个节点开始,对其子树进行中序遍历,同时用一个vector储存节点。代码中未...

weixin_44111457的博客 2048

【ChatGPT实战案例】ChatGPT如何帮助产品经理高效工作?

1. 产品经理主要工作方向, 2. 具体工作中,向ChatGPT提问参考

weixin_62909516的博客 1893

平衡二叉树-替罪羊树 c/c++代码实现

参考:https://www.bilibili.com/video/BV1Wt411L7te?t=1822大佬视频 需要重构的条件是:当前结点的左子树或右子树的大小大于当前结点的大小乘一个平衡因子alpha或者以当前节点为根的子树内被删除的结点数量大于树大小的30%了 代码中有比较详细的注释 /*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> const

xxxxxiao123的博客 608

【新手必看】蓝牙的HOGP和HID、GATT有什么区别和联系

让新手宏观了解蓝牙HOGP、HID、GATT这三个协议的区别和联系

qq_51976334的博客 1561

绑定压力的计算方法

压强的公式为P=F/S,其中P为ACF要求的本压压强范围,S为受压面积,F为本压压头施加的力。绑定参数需要按线体按压头进行DOE确认,并使用DOE确认好的参数按压头重新绑定标识好送ACF厂商实测固化率、粒子变形的情况,避免绑定参数导致的异常,在绑定参数的设定过程中温度和时间可以使用仪器实测但绑定的压力则需要换算。工程上绑定压力换算的原则是:1、FPC属于柔性物料,柔性物料的受压面积按FPC绑定的受压面积=FPC绑定的长度。一、工程上FOG FPC本压压力换算(柔性材料以挤压的接触面积=受力面积)F=P。

weixin_53757859的博客 1525

替罪羊树模板

P3369 【模板】普通平衡树 注意!!!!!!!!!!!!!! 由于题目限制:该模板没有考虑,删除节点不存在的情况。 #include <bits/stdc++.h> #define inf 0x7fffffff #define ll long long //#define int long long //#define double long double //#define double long long #define re register int //#define void in

lcl1234567890lcl的博客 119

国产麒麟系统PXE安装-UEFI引导

注意: 适用uefi引导 适用x86_64架构 一键部署脚本扣我 1.上传ISO到PXE服务器,拷贝ISO文件 # mkdir /kylin_iso # mount -o loop Kylin-Server-10-SP1-Release-Build04-20200711-x86_64.iso /kylin_iso/ 2.配置http,获取安装源 # yum -y install httpd # mkdir /var/www/html/{ks,kylin} # 注意一定是"/kylin_iso/

河静 5044

替罪羊树(Scapegoat Tree)

替罪羊树,一种基于暴力重构的平衡树

KaiserWilheim的博客 3037

56、宇宙微波背景辐射(CMB)望远镜及光学系统解析

本文详细解析了宇宙微波背景辐射(CMB)望远镜及其光学系统,重点介绍了交叉德拉贡系统的结构特点、偏振测量误差及其控制、以及大型地面望远镜如ACT和SPT的设计与对比。同时,总结了不同光学系统和探测器阵列的优劣势,并展望了未来发展方向,旨在为CMB研究提供更高效的工具和技术支持。

f9g0h的博客 237

海思3559av100平台lan9500模块调试记录

1. 前言 通过USB2.0接口扩展一路百兆虚拟网口 2. 配置lan9500驱动 make ARCH=arm64 menuconfig 开启LAN95XX驱动,编译进内核 保存内核配置 3. 编译内核 make ARCH=arm64 CROSS_COMPILE=aarch64-himix100-linux- uImage -j 20 cd ../../arm-trusted-firmware/arm-trusted-firmware ./mk.sh cp ...

jzwjzw19900922的博客 905

OI国家集训队论文集1999~2018

直接放网盘: 链接:https://pan.baidu.com/s/1YqJmBVRd_ZNztU3EgW1RoQ 提取码:xj20 复制这段内容后打开百度网盘手机App,操作更方便哦 最重要的还是以上东西 以下图片和文字(没啥暖用,就是看起来整体清楚点)摘自别人博客:https://blog.csdn.net/qq_41551359/article/details/9396488...

ltrbless的博客 5004

深入详解DICOM医学影像定位线相关知识:理解定位线的概念、定位线的作用以及定位线显示和计算原理

深入详解DICOM医学影像定位线相关知识:理解定位线的概念、定位线的作用以及定位线显示和计算原理

编程技术探索者,分享C/C++、C#、Java、数据库等开发经验,聚焦实战技巧与AI兴趣,助力编程爱好者成长。 2041

替罪羊树学习日记

昨天晚上wq学长讲课,讲完让人略微懵逼的KD-tree,学长心血来潮要讲替罪羊树 学长:尽管这个玩意又臭又长,但是我从学会一直打到了退役,你们今天晚上和明天上午可以不看板子自己YY一下 一向乖巧听话(人怂胆小)的我觉得学长说得对啊,然后第二天早上我欣然开始了替罪羊树之旅,并不知道后面等着我的是什么 刚开始非常顺利得码完,和ce抗衡取得成功,然后输入样例,RE 然后发现插入时没处理...

weixin_30294021的博客 122

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

替罪羊树

文章目录替罪羊树1.算法分析2.模板3.典型例题 替罪羊树 1.算法分析 替罪羊树 是一种依靠重构操作维持平衡的重量平衡树。替罪羊树会在插入、删除操作时,检测途经的节点,若发现失衡,则将以该节点为根的子树重构。重构的操作是先做一遍中序遍历,然后按照中点分治拎起来。 2.模板 // 该模板删除操作时必须保证树内有这个点 #include <bits/stdc++.h> using namespace std; int const N = 1e5 + 10; const double alpha

m0_49959202的博客 294

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【模板】替罪羊树

本来是打开了一道点分治的题,后来发现要用高速平衡树 据说splaysplaysplay和fhq&amp;nbsp;Treapfhq\ Treapfhq&amp;nbsp;Treap都非常非常的慢 据说替罪羊树是除了红黑树以外最快的平衡树? 于是就来学习了一下 核心思想就是每次插入不改变树的形态,当树极不平衡时就把它拍扁重构 alpha=0.8alpha=0.8alpha=0.8的时候据说最快 模板题:luoguP...

继续学吧 508

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

替罪羊树学习模板

替罪羊树学习模板。供算法竞赛学生学习。

2401_84097724的博客 514

P3369 【模板】普通平衡树(替罪羊树)

题目链接:https://www.luogu.com.cn/problem/P3369 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入 x 数 删除 x 数(若有多个相同的数,因只删除一个) 查询 x 数的排名(排名定义为比当前数小的数的个数 +1 ) 查询排名为 x 的数 求 x 的前驱(前驱定义为小于 x,且最大的数) 求 x 的后继(后继定义为大...

zaiyang遇见 663

模板:替罪羊树

替罪羊树模板 Code(指针版): #include <bits/stdc++.h> using namespace std; typedef long long ll; bool Finish_read; template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=g...

dieyi9889的博客 114

P3369 【模板】普通平衡树 [替罪羊树做法]

替罪羊树

Ajwallet 596

替罪羊树的原理及实例

[Scapegoat Tree] & BZOJ3224 识替罪羊树之算法乃吾生之幸也! 0x00 扯淡 知乎上面有个问题问最优雅的算法是什么,我觉得暴力即是优雅。 当然这里说的暴力并不是指那种不加以思考的无脑的暴力,而是说用繁琐而技巧性的工作可以实现的事,我用看似简单的思想和方法,也可以达到近似于前者的空间复杂度和时间复杂度,甚至可以更优,而其中也或多或少...

dianshu1593的博客 668

五分钟看懂——替罪羊树

这个名字取得比较玄乎,一眼看上去并不知道有什么卵用,但是, 如果你是刚学平衡树的新手,那么从替罪羊树开始学一定是个绝佳的选择,因为它是个很优雅的平衡树,什么叫优雅?暴力即是优雅! 如果在一棵平衡的二叉搜索树内进行查询等操作,时间就可以稳定在log(n),但是每一次的插入节点和删除节点,都可能会使得这棵树不平衡,最坏情况就是退化成一条链,显然我们不想要这种树,于是各种维护的方法出现了,大部分的平衡树...

无 990
上一篇: BZOJ4518——二维斜率优化dp
下一篇: LUOGU4360[CEOI2004]锯木厂选址——斜率优化dp
stevensonson
博客等级 码龄9年 31粉丝 181原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值