洛谷P3919 【模板】可持久化数组 [主席树]
可持久化数组
题目描述
如题,你需要维护这样的一个长度为 $N$ 的数组,支持如下几种操作
在某个历史版本上修改某一个位置上的值
访问某个历史版本上的某一位置的值
此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组)
输入输出格式
输入格式:
输入的第一行包含两个正整数 $N, M$, 分别表示数组的长度和操作的个数。
第二行包含 $N$ 个整数,依次为初始状态下数组各位的值(依次为 $a_i$, $1 \leq i \leq N$ )。
接下来 $M$ 行每行包含3或4个整数,代表两种操作之一( $i$ 为基于的历史版本号):
对于操作1,格式为 $v_i \ 1 \ {loc}_i \ {value}_i$ ,即为在版本 $v_i$ 的基础上,将 $a_{{loc}_i}$ 修改为 ${value}_i$
对于操作2,格式为 $v_i \ 2 \ {loc}_i$ ,即访问版本 $v_i$ 中的 $a_{{loc}_i}$ 的值
输出格式:
输出包含若干行,依次为每个操作2的结果。
输入输出样例
5 10
59 46 14 87 41
0 2 1
0 1 1 14
0 1 1 57
0 1 1 88
4 2 4
0 2 5
0 2 4
4 2 1
2 2 2
1 1 5 91
59
87
41
87
88
46
说明
数据规模:
对于30%的数据: $1 \leq N, M \leq {10}^3$
对于50%的数据: $1 \leq N, M \leq {10}^4$
对于70%的数据: $1 \leq N, M \leq {10}^5$
对于100%的数据: $1 \leq N, M \leq {10}^6, 1 \leq {loc}_i \leq N, 0 \leq v_i < i, -{10}^9 \leq a_i, {value}_i \leq {10}^9$
经测试,正常常数的可持久化数组可以通过,请各位放心
数据略微凶残,请注意常数不要过大
另,此题I/O量较大,如果实在TLE请注意I/O优化
询问生成的版本是指你访问的那个版本的复制
分析:
可持久化数据结构的一个好板子,这里蒟蒻用的是可持久化线段树(因为只会这个)。
每次操作的时候,复制询问的前一个状态的路径即可。另外询问操作直接把那一次的root修改为当前询问的历史版本的root。
Code:
//It is made by HolseLee on 5th Aug 2018
//Luogu.org P3919
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std; const int N=1e6+;
int n,m,root[N],a[N],cnt;
struct node{
int ls,rs,val;
};
struct Seg{
node seg[N*]; inline void build(int &rt,int l,int r)
{
rt=++cnt;
if(l==r){
seg[rt].val=a[l];return;
}
int mid=(l+r)>>;
build(seg[rt].ls,l,mid);
build(seg[rt].rs,mid+,r);
} inline void update(int &rt,int last,int l,int r,int pos,int v)
{
rt=++cnt;
seg[rt].ls=seg[last].ls,seg[rt].rs=seg[last].rs;
seg[rt].val=seg[last].val;
if(l==r){
seg[rt].val=v;return;
}
int mid=(l+r)>>;
if(pos<=mid)update(seg[rt].ls,seg[last].ls,l,mid,pos,v);
else update(seg[rt].rs,seg[last].rs,mid+,r,pos,v);
} inline int quary(int rt,int l,int r,int pos)
{
if(l==r)return seg[rt].val;
int mid=(l+r)>>;
if(pos<=mid)return quary(seg[rt].ls,l,mid,pos);
else return quary(seg[rt].rs,mid+,r,pos);
}
}T; inline int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
} int main()
{
n=read();m=read();
for(int i=;i<=n;++i)a[i]=read();
T.build(root[],,n);
int pre,pos,value,op;
for(int i=;i<=m;++i){
pre=read();op=read();pos=read();
if(op==){
T.update(root[i],root[pre],,n,pos,read());
}
else {
printf("%d\n",T.quary(root[pre],,n,pos));
root[i]=root[pre];
}
}
return ;
}
洛谷P3919 【模板】可持久化数组 [主席树]的更多相关文章
- P3919 (模板)可持久化数组 (主席树)
题目链接 Solution 主席树水题,连差分的部分都不需要用到. 直接用主席树的结构去存一下就好了. Code #include<bits/stdc++.h> #define mid ( ...
- 【洛谷P3919】可持久化数组
题目大意:需要维护一个长度为 N 的数组,支持在历史版本上单点修改和单点查询. 题解:显然,如果直接暴力维护的话会 MLE.因此,采用线段树进行维护,使得空间复杂度由 \(O(mn)\) 降至 \(O ...
- luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)
luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include< ...
- 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]
题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...
- 洛谷.3835.[模板]可持久化平衡树(fhq treap)
题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- LOJ 2555 & 洛谷 P4602 [CTSC2018]混合果汁(二分+主席树)
LOJ 题目链接 & 洛谷题目链接 题意:商店里有 \(n\) 杯果汁,第 \(i\) 杯果汁有美味度 \(d_i\),单价为 \(p_i\) 元/升.最多可以添加 \(l_i\) 升.有 \ ...
- 洛谷P2633 Count on a tree(主席树上树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
- 洛谷P4587 [FJOI2016]神秘数(主席树)
题面 洛谷 题解 考虑暴力,对于询问中的一段区间\([l,r]\),我们先将其中的数升序排序,假设当前可以表示出\([1,k]\)目前处理\(a_i\),假如\(a_i>k+1\),则答案就是\ ...
随机推荐
- [吴恩达机器学习笔记]12支持向量机4核函数和标记点kernels and landmark
12.支持向量机 觉得有用的话,欢迎一起讨论相互学习~Follow Me 12.4 核函数与标记点- Kernels and landmarks 问题引入 如果你有以下的训练集,然后想去拟合其能够分开 ...
- ① 设计模式的艺术-07.适配器(Adapter)模式
什么是适配器模式? 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 模式中的角色 目标接口(Target):客户所期待的接口 ...
- PowerShell入门
最近需要写个Windows的脚本,以前一直使用cmd.exe来写批处理脚本,这次接触到了PowerShell,准备把学习过程中学到的知识点整理在这里: 相关文章: 1.https://www.cnbl ...
- GridControl详解(六)样式设置
表格样式:全局设置 例子: 例子: 列样式:只作用于当前的列 通用样式:外观设定 注意:样式设定都是相同的,Appearance前缀.
- 母版页 VS shtml—ASP.NET细枝末节(3)
这算是html的重用吧? 网页很多地方长得一样,也有不一样的地方. 把网页中一样的地方,提取出来,形成一个文档. 在其他网页中引用,是网站开发的一个传统的思维. 当然不同的技术有不同的表现形式. 例如 ...
- 小程序制作中 一个奇怪的bug
事情是这样的:原一个购物车 合并本地数据和服务器 数据方法如下 ,正常测试没有问题,当每次重新登录,会调用到这个方法,就会莫名其妙的卡主,debug 发现 a1.length =77731508 导致 ...
- mysql数据库 批量替换 某字段中的数据
当数据库出现这种情况: 表名:area id name 1 太仓 2 太仓市 3 太仓市 ... ... 我需要把 name字段中 的太仓市 的“市“去掉 可以使用: update `area` ...
- NYOJ 1022 合纵连横 (并查集)
题目链接 描述 乱世天下,诸侯割据.每个诸侯王都有一片自己的领土.但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大.而实力弱的诸侯王为了不让自己的领 ...
- 24、简述Python的深浅拷贝以及应用场景
深浅拷贝的原理 深浅拷贝用法来自copy模块. 导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝 ...
- php常用函数——字符串函数
php常用函数——字符串函数