当前位置:网站首页>可持久化线段树
可持久化线段树
2022-08-01 04:51:00 【glorious_dream】
为什么叫可持久化线段树(主席树) :发明人是黄嘉泰 (hjt) 想到了谁?
何为可持久化线段树?
考虑这样一道题目

也就是说,在线段树的基础上,需要支持回退到某一个版本。
首先,最暴力的方式,肯定是每一个版本都建一棵线段树,但空间肯定爆炸。
所以考虑优化,让每一个版本修改的数量尽量变少。

在修改版本中,只需要修改logn个节点,其余节点和原来的线段树共用,这样就可以省掉很大一部分空间。注意实现的时候要记录下来每一个版本的根节点的编号。
其余的各种操作和线段树类似。
#include<bits/stdc++.h>
#define re register
#define rep(a,b,c) for(re int a(b) ; a<=c ; ++a)
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
return x*f;
}
const int M = 2e7+5e6;
const int N = 1e6+10;
int a[N],root[N];
int top;
struct tree{
int l,r,val;
}t[M];
int n,m;
struct qwq{
inline int clone(int node){ //新建一个版本,要把原版本的信息复制给新的版本
t[++top] = t[node];
return top;
}
inline int build(int node,int l,int r){
node = ++top;
if(l == r){
t[node].val = a[l]; //建树
return node;
}
int mid = (l+r)>>1;
t[node].l = build(t[node].l,l,mid);
t[node].r = build(t[node].r,mid+1,r);
return node; //返回根节点的编号
}
inline int modify(int node,int l,int r,int x,int y){
node = clone(node); //新的节点编号
if(l == r) t[node].val = y;
else{
int mid = (l+r)>>1;
if(x<=mid) t[node].l = modify(t[node].l,l,mid,x,y);
else t[node].r = modify(t[node].r,mid+1,r,x,y); //与线段树的操作类似
}
return node;
}
inline int query(int node,int l,int r,int x){
if(l == r) return t[node].val;
else{
int mid = (l+r)>>1;
if(x<=mid) return query(t[node].l,l,mid,x);
else return query(t[node].r,mid+1,r,x);
}
}
}pst;
signed main(){
scanf("%d%d",&n,&m);
rep(i,1,n) a[i] = read();
root[0] = pst.build(0,1,n); //第0个版本的根节点的编号
rep(i,1,m){
int rt,op,x;
scanf("%d%d%d",&rt,&op,&x);
if(op == 1){
int y=read();
root[i] = pst.modify(root[rt],1,n,x,y); //记录下来每一个版本根节点的编号
}
else{
printf("%d\n",pst.query(root[rt],1,n,x));
root[i] = root[rt]; //询问也算一次操作
}
}
return 0;
}
边栏推荐
- PMP 项目沟通管理
- (2022 Nioke Duo School IV) H-Wall Builder II (Thinking)
- 报错:AttributeError: module ‘matplotlib’ has no attribute ‘figure’
- Mysql基础篇(约束)
- y83.第四章 Prometheus大厂监控体系及实战 -- prometheus告警机制进阶(十四)
- typescript21 - Comparison of Interfaces and Type Aliases
- 请问shake数据库中想把源的db0的数据同步到目的db5,参数怎么设置呢?
- typescript23-元组
- 产品经理访谈 | 第五代验证码的创新与背景
- Invalid classes inferred from unique values of `y`. Expected: [0 1 2], got [1 2 3]
猜你喜欢
随机推荐
Visual Studio提供的 Command Prompt 到底有啥用
25. Have you been asked these three common interview questions?
智芯传感输液泵压力传感器 为精准智能控制注入科技“强心剂”
Mysql基础篇(约束)
MLP neural network, GRNN neural network, SVM neural network and deep learning neural network compare and identify human health and non-health data
typescript25-类型断言
雪糕和轮胎
Pyspark Machine Learning: Vectors and Common Operations
(2022牛客多校四)N-Particle Arts(思维)
挑战52天背完小猪佩奇(第01天)
UE4 rays flashed from mouse position detection
Lawyer Interpretation | Guns or Roses?Talking about Metaverse Interoperability from the Battle of Big Manufacturers
/etc/fstab
请问表格储存中用sql只能查询到主键列,ots sql非主键不支持吗?
力扣(LeetCode)212. 单词搜索 II(2022.07.31)
Swastika line-by-line parsing and realization of the Transformer, and German translation practice (2)
safari浏览器怎么导入书签
mysql中解决存储过程表名通过变量传递的方法
TIM登陆时提示00001(TIM00001)
PAT serie b write the number 1002









