【Luogu P3834】可持久化数组(可持久化线段树)
题目链接
可持久化线段树模板题。
这里总结一下可持久化线段树。
可持久化数据结构就是能恢复历史状态的数据结构,比如可持久化\(Trie\),并查集,平衡树。
可持久化数组是最基础的,这里通过可持久化线段树来实现。
可持久化线段树
·复杂度:时间\(O(n\log n)\),空间\(O(m\log n)\)。
·实现:
这里只针对单点修改的可持久化,区间修改是很复杂的。
可以发现,线段树的每次单点修改只会改变树上的\(\log n\)个节点,于是我们对这\(\log n\)个节点创建副本,如图(自绘丑)

红点是我们要修改的点,红边经过的点都是值会发生变化的,我们对其建立副本,如图:

可以看到,每个被修改的点一个副本,和没被修改的点正常连边,这样每次操作只会增加\(\log n\)个节点。
然后我们每次修改把修改后的副本的根记录下来,如图:

然后从这个根遍历树,就是我们要的历史版本了。
代码实现:
#include <cstdio>
#define re register
inline int read(){
s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
return s * w;
}
const int MAXN = 1000010;
const int MAXM = 1000010;
struct SegTree{
int lc, rc, val;
SegTree(){ lc = rc = val = 0; }
}t[MAXM * 20];
int tot, a[MAXN], root[MAXN];
int build(int l, int r){
int id = ++tot;
if(l == r){ t[id].val = a[l]; return id; }
int mid = (l + r) >> 1;
t[id].lc = build(l, mid);
t[id].rc = build(mid + 1, r);
return id;
}
int insert(int now, int l, int r, int x, int p){
int id = ++tot; //创立副本
t[id] = t[now]; //先与原点保持一致
if(l == r){ t[id].val = p; return id; } //修改副本(不改原点)
int mid = (l + r) >> 1;
if(x <= mid) t[id].lc = insert(t[now].lc, l, mid, x, p); //只把改变的儿子变为副本,另一个儿子仍是原来的
else t[id].rc = insert(t[now].rc, mid + 1, r, x, p);
return id; //返回副本编号
}
int ask(int now, int l, int r, int x){ //查询和普通线段树没有区别
if(l == r) return t[now].val;
int mid = (l + r) >> 1;
if(x <= mid) return ask(t[now].lc, l, mid, x);
else return ask(t[now].rc, mid + 1, r, x);
}
int n, m;
int v, opt;
int A, B;
int main(){
n = read(); m = read();
for(int i = 1; i <= n; ++i)
a[i] = read();
root[0] = build(1, n); //初始版本
for(int i = 1; i <= m; ++i){
v = read(); opt = read();
if(opt == 1){
A = read(); B = read();
root[i] = insert(root[v], 1, n, A, B); //在版本v的基础上把位置A上的数变为B
}
else{
A = read();
printf("%d\n", ask(root[v], 1, n, A));
root[i] = root[v];
}
}
return 0;
}
【Luogu P3834】可持久化数组(可持久化线段树)的更多相关文章
- luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)
luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include< ...
- Luogu 3373 又乘又加的线段树
Luogu 3373 又乘又加的线段树 当给一个节点加上一个加法标记时,直接把加法标记 += 新值: 当给一个节点加上一个乘法标记时,把乘法标记和加法标记同时 *= 新值.(注意pushdown函数中 ...
- Luogu P3919 【模板】可持久化数组 可持久化线段树
其实就是可持久化线段树的模板题线段树不会看这里 #include<bits/stdc++.h> ; using namespace std; ]; ],rc[N*],val[N*],cnt ...
- luogu P3834 【模板】可持久化线段树 1(主席树) 查询区间 [l, r] 内的第 k 小/大值
————————————————版权声明:本文为CSDN博主「ModestCoder_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https:// ...
- P3919 【模板】可持久化数组 -初步探究主席树
本篇blog主要是给自己(大家)看的. 感谢longlongzhu123奆佬(此人初二LCT)的指点,使本蒟蒻可以快速开始主席树入门. what is 主席树? $ $主席树这个名字只不 ...
- Luogu 45887 全村最好的嘤嘤刀(线段树 树状数组)
https://www.luogu.org/problemnew/show/T45887 题目背景 重阳节到了,我们最好的八重樱拥有全村最好的嘤嘤刀…… 题目描述 在绯玉丸力量的影响下,八重村成了一条 ...
- BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...
- HDU 1166 敌兵布阵 (数状数组,或线段树)
题意:... 析:可以直接用数状数组进行模拟,也可以用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo ...
- 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 418 Solved: 235 [ Submit][ ...
随机推荐
- 为什么说Objective-C是一门动态的语言?
object-c类的类型和数据变量的类型都是在运行是确定的,而不是在编译时确定.例如:多态特性,我们可以使用父类对象来指向子类对象,并且可以用来调用子类的方法.运行时(runtime)特性,我们可以动 ...
- 数据库学习(四)with as (补充 nvl 和 count 函数)
with as 的专业解释我这就不详细说明了,我这就梳理下我自己的实践应用,就是根据某个条件查询出结果集放在一个临时表里面,可以创建多个临时表,然后再从这些临时表中查询出要的数据. 参考资料:http ...
- CSP201512-1: 数位之和
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- Spring实战第一章学习笔记
Spring实战第一章学习笔记 Java开发的简化 为了降低Java开发的复杂性,Spring采取了以下四种策略: 基于POJO的轻量级和最小侵入性编程: 通过依赖注入和面向接口实现松耦合: 基于切面 ...
- zabbix从入门到精通
第1章 zabbix监控 1.1 为什么要监控 在需要的时刻,提前提醒我们服务器出问题了 当出问题之后,可以找到问题的根源 网站/服务器 的可用性 1.1.1 网站可用性 在软件系统的高可靠性(也 ...
- sqlserver2012 查询远程数据库
EXEC sp_addlinkedserver 'LinkName','','SQLOLEDB','121.43.177.236'EXEC sp_addlinkedsrvlogin 'LinkName ...
- [转]Hibernate入门:批量插入数据
转自:http://blog.csdn.net/xiazdong/article/details/7709068 一般如果要插入100万条数据,则会写如下代码: package org.xiazdon ...
- [leetcode-646-Maximum Length of Pair Chain]
You are given n pairs of numbers. In every pair, the first number is always smaller than the second ...
- To Chromium之浏览器外框UI(2)
之前一些文章本来是草稿状态,一次性全release出来了,排版上可能看上去不太舒服,等哪一天研究下改改排版. Here继续chromium的UI,看看,浏览器的外壳是怎么被画出来的:) 可以先关注下几 ...
- 变量可以通过into赋值