首页 > 其他分享 >浅析FHQ-treap

浅析FHQ-treap

时间:2024-12-29 19:41:07浏览次数:1  
标签:return val rs int treap ls now FHQ 浅析

前言

更好的阅读体验
默认读者会 BST 的基本操作。

节点定义

替罪羊树采用了懒惰删除的方法,不会立即删除某个点,而是在重构时不放进数组。

struct node{  
    int ch[2], val;  
    int siz1, siz2, cnt, sum;  
    //扣去懒惰删除的节点数量,没扣去懒惰删除的节点数量,树内相同权值的数量,子树大小。  
}d[N];  
int root, tot, stk[N], top, v[N], t;//stk 是垃圾回收  
double al = 0.75;  
#define ls(x) d[x].ch[0]  
#define rs(x) d[x].ch[1]  
int newnode(int x){  
    int w = top ? stk[top--] : ++tot;  
    return d[w].val = x, ls(w) = rs(w) = 0, d[w].cnt = 1, pushup(w), w;  
}  
void pushup(int x){  
    node&rt = d[x],ls = d[ls(x)],rs = d[rs(x)];  
    rt.siz1 = (rt.cnt > 0) + ls.siz1 + rs.siz1;  
    rt.siz2 = 1 + ls.siz2 + rs.siz2;  
    rt.sum = rt.cnt + ls.sum + rs.sum;  
}  

重构

BST 最担心的是树退化成链。
那么有个暴力的想法:
把树拍扁放进数组,然后重新构建一棵完全二叉树。
但是过多的重构会使复杂度上升,那么我们引入一个概念:\(\alpha\)
\(\alpha = \dfrac{\max(siz2_{ls}, siz2_{rs}) }{siz2_{rt}}\)
一般的平衡树都能把 \(\alpha\) 维护在 \([0.6, 0.8]\) 左右。

我们可以将 \(\max\alpha\) 设为一个数,一般为 \([0.7,0.8]\)。
一般选 \(0.75\)。
在某个节点的 \(\alpha > \max \alpha\) 时,我们把这个子树重构。
如果这个树 \(siz1 \le \alpha siz2\),那么我们认为它也是需要重构的。
比如这棵树:
tu

那么我们将它拍扁放进数组。
tu
然后像线段树一样重新建树。
tu

#define check(x) x&&(al*d[x].siz2<=max(d[ls(x)].siz2,d[rs(x)].siz2)||d[x].siz1<=0.75*d[x].siz2)  
void dfs(int x){  
    if(!x)return;  
    dfs(ls(x)), (d[x].cnt ? v[++t] : stk[++top]) = x, dfs(rs(x));  
}  
int build(int l, int r){  
    if(l == r)return ls(v[l]) = rs(v[l]) = 0, pushup(v[l]), v[l];  
    if(l > r)return 0;  
    int mid = l + r >> 1, x = v[mid];  
    ls(x) = build(l, mid - 1), rs(x) = build(mid + 1, r);  
    return pushup(x), x;  
}  
#define refactoring(x) t = 0, dfs(x), x = build(1, t)  

插入

如果在当前节点的权值和要插入的权值一样,我们将 \(cnt\) 增加。
其他和 BST 一样。
记得在回溯时更新节点,判断是否重构。

void insert(int&now, int val){  
    if(!now)return void(now = newnode(val));  
    if(d[now].val == val)d[now].cnt++;  
    else if(d[now].val < val)insert(rs(now), val);  
    else insert(ls(now), val);  
    pushup(now);  
    if(check(now))refactoring(now);  
}  

删除

懒惰删除,只是将 \(cnt\) 减少。
然后在回溯时更新节点,判断是否重构。

void del(int&now, int val){  
    if(!now)return;  
    if(d[now].val == val)d[now].cnt--;  
    else if(d[now].val < val)del(rs(now), val);  
    else del(ls(now), val);  
    pushup(now);  
    if(check(now))refactoring(now);  
}  

查询操作

这部分就差不多了。

int kth(int x){  
    int now = root, siz = 0, z = x;  
    while(now){  
        if((siz = d[ls(now)].sum) >= x)now = ls(now);  
        else if((siz += d[now].cnt) < x)x -= siz, now = rs(now);  
        else return d[now].val;  
    }  
    return -1;  
}  
int query_rank(int val){  
    int ans = 1, now = root;  
    while(now){  
        if(d[now].val == val)ans += d[ls(now)].sum, now = 0;  
        else if(d[now].val < val)ans += d[ls(now)].sum + d[now].cnt, now = rs(now);  
        else now = ls(now);  
    }  
    return ans;  
}  
int ask_pre(int val){return kth(query_rank(val) - 1);}  
int ask_next(int val){return kth(query_rank(val + 1));}  

代码

完整代码

标签:return,val,rs,int,treap,ls,now,FHQ,浅析
From: https://www.cnblogs.com/fush/p/18639439

相关文章

  • Midjourney技术浅析(五):图像细节处理
    Midjourney 作核心目标之一是生成高质量、高分辨率且细节丰富的图像。为了实现这一目标,Midjourney 采用了超分辨率(Super-Resolution)和细节增强(DetailEnhancement)技术。本文将深入探讨Midjourney的超分辨率与细节增强模块,包括生成对抗网络(GAN)、卷积神经网络(CNN)、图像滤波(Im......
  • uniapp不能直接修改props的数据原理浅析
    uniapp不能直接修改props的数据Avoidmutatingapropdirectlysincethevaluewillbeoverwrittenwhenevertheparentcomponentre-renders.Instead,useadataorcomputedpropertybasedontheprop'svalue.Propbeingmutated:"expectDeliveryAt"......
  • Midjourney技术浅析(一)
    Midjourney 是一款基于人工智能的图像生成工具,能够根据用户输入的文本描述生成高质量的图像。其核心技术涉及多个领域,包括自然语言处理(NLP)、计算机视觉(CV)、深度学习(DL)等。一、Midjourney的工作原理概述Midjourney 的工作流程如下:1.文本理解与编码(TextUnderstandingand......
  • 浅析时钟缓冲器的选型|你真的选对buffer了吗?
    时钟缓冲器就是常说的ClockBuffer,主要分为扇出缓冲器和零延迟缓冲器。时钟缓冲器(Buffer)本身是无法产生频率源的,它的主要作用是将晶体或晶振产生的时钟信号进行复制、格式转换及电平转换。 选对合适的时钟Buffer,可以起到平替晶体或晶振,降低系统成本的作用。扇出型缓冲器,究......
  • Move AI技术浅析(二):输入与预处理
    一、视频输入模块1.1视频输入步骤详解视频输入模块的主要任务是接收视频数据,并将其转换为后续处理所需的格式。具体步骤:1.1.1视频读取步骤:从文件系统、网络流或摄像头读取视频数据。技术:使用 OpenCV 的 cv2.VideoCapture 函数读取视频文件或摄像头视频流。示例代码:i......
  • 大模型应用技术系列(一):大模型应用整体技术栈浅析
        RAG相关的技术学习暂时告一段落了,接下来尝试探索新的学习方向。这就引入一个问题:接下来该做什么?为了能进一步推进,我需要有一个整体的视角,从更上层来看整个技术栈,从而确定接下来感兴趣的方向。本文主要探索从更上层的视角来看构建大模型的技术栈,从而进一步确定研究......
  • 数智化医院分布式计算框架融合人工智能方向初步实现与能力转换浅析
    人工智能中心计算机一、引言1.1研究背景与意义近年来,人工智能(ArtificialIntelligence,AI)与大数据技术的迅猛发展为医疗行业带来了前所未有的变革机遇。医疗领域积累了海量的数据,如电子病历(ElectronicMedicalRecord,EMR)、医学影像、临床检验数据以及基因数据等。这些数......
  • Pika Labs技术浅析(五):商业智能技术
    Pika Labs 的商业智能旨在通过联机分析处理(OLAP)和数据仓库(Data Warehouse)等技术,帮助企业用户高效地进行数据分析和决策支持。一、商业智能技术模块概述Pika Labs 的商业智能技术模块旨在通过集成数据仓库和联机分析处理技术,帮助企业用户进行多维度的数据分析和决策支持......
  • Pika Labs技术浅析(四):数据可视化
    Pika Labs的数据可视化技术模块提供了丰富的可视化库和自适应仪表盘功能,能够帮助用户高效地展示和分析数据。一、数据可视化技术模块概述Pika Labs 的数据可视化技术模块旨在通过直观的图表和仪表盘,帮助用户快速理解数据趋势、模式和异常。该模块主要包含两个核心部分:1......
  • FHQ-treap 学习笔记
    FHQ-Treap学习笔记範浩強之木,無旋之奇構,併合眸,妙用無窮;其當官也,避繁複之旋。其視心有二,分若離,合若聚,若星漢分合變幻,肖無跡矣。不用旋,巧避繁,古之所未有,今之所獨異。茲樹形奇,如天成,真算之妙。---------《算枢奇构》###基本操作众所周知,无旋treap不需要旋转,基本操作有两个,分......