可持久化线段树(主席树)

今天讲了下可持久化线段树,在熟练线段树的前提下听起来还是比较轻松,不过好像操作比较多,变形也比较多,所以写博客巩固基础(大佬跳过吧)
前置知识 熟练掌握的[线段树]

可持久化

首先“可持久化”这个初次见到的看似专业的名词并不只是适用于线段树,它只是一种思想,顾名思义-----持久。当你的数据结构中有一个点被修改了多次以后(例如修改了k次),但仍然能找到修改第q(0<=q<k)次的状态便是可持久化,除线段树以外,还有其它的数据结构都能持久化,例如:字典树,单链表等。
听到此处迷迷糊糊很正常,本博客讨论你的重点是可持久化的线段树,只需要知道可持久化的一点概念即可。

可持久化线段树(主席树)

它有一个很常见的名字——主席树。它的主体是线段树,准确的说,是很多棵线段树。
陈立杰、Seter、Fotile等人称这种以值域作为区间长度的线段树为权值线段树。
学会的小朋友可以去秀一秀。
First:一个普通线段树建图后的效果
在这里插入图片描述
Second:线段树的操作无非就是修改,不过因为‘‘可持久化’’的出现,所以也有插入操作,先考虑修改
既然要将原本的状态留下,那我们考虑一种方案,也是最容易想到的,将原本的线段树复制一份,用另外一个数组存储一个新的线段树。但是,我们想想:线段树所维护的序列长度为n,线段树的大小一般开(n<<2),所以一棵线段树所需空间(n<<2)。再者q次修改,复制q份线段树,那么空间复杂度q ⋅ \cdot (n<<2)。如果q,n中任何一个数超过10000,就基本没戏。
所以考虑其他方法:既然是修改一个点,那么只是这个点所对应的一条链进行修改,其它都没有变,那么我们只需要储存一条链,在线段树中,链长度是logn,因为q次修改,所以复制q条链,那么只需要在原线段树的基础上开q ⋅ \cdot logn的空间记录新加入的链即可。例如,改左下角的点会影响的链
在这里插入图片描述
Third:复制这条链在这里插入图片描述
插入第一个元素后,土红色是新生成的结点,它们属于第一次修改后的状态,其余的深棕色属于初始化状态,即第一次状态。每插入一个元素,仅新增log(n)个结点,耗时log(n),因此建树的时间、空间均为nlog(n)

[福利]可持久化线段树

为什么说本题是福利呢?因为这是一道非常直白的可持久化线段树的练习题,目的并不是虐人,而是指导你入门可持久化数据结构

线段树有个非常经典的应用是处理RMQ问题,即区间最大/最小值询问问题。现在我们把这个问题可持久化一下:
Q k l r 查询数列在第k个版本时,区间[l, r]上的最大值
M k p v 把数列在第k个版本时的第p个数修改为v,并产生一个新的数列版本
最开始会给你一个数列,作为第1个版本。每次M操作会导致产生一个新的版本。
修改操作可能会很多呢,如果每次都记录一个新的数列,空间和时间上都是令人无法承受的。
所以我们需要可持久化数据结构:
对于最开始的版本1,我们直接建立一颗线段树,维护区间最大值。
修改操作呢?我们发现,修改只会涉及从线段树树根到目标点上一条树链上logn个节点而已,其余的节点并不会受到影响。所以对于每次修改操作,我们可以只重建修改涉及的节点即可。就像这样:
需要查询第k个版本的最大值,那就从第k个版本的树根开始,像查询普通的线段树一样查询即可。

#include <cstdio>
#include <iostream>
#include <algorithm>
#define Int register int
const int N = 100000;
using namespace std;

static inline char Get_Char() {
   
	static char buffer[100000], *S = buffer, *T = buffer;
	if (S == T) {
   
		T = (S = buffer) + fread(buffer, 1, 100000, stdin);
		if (S == T) return EOF;
	}
	
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值