题目传送门

可持久化数组

题目描述

如题,你需要维护这样的一个长度为 $N$ 的数组,支持如下几种操作

  1. 在某个历史版本上修改某一个位置上的值

  2. 访问某个历史版本上的某一位置的值

此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组)

输入输出格式

输入格式:

输入的第一行包含两个正整数 $N, M$, 分别表示数组的长度和操作的个数。

第二行包含 $N$ 个整数,依次为初始状态下数组各位的值(依次为 $a_i$, $1 \leq i \leq N$ )。

接下来 $M$ 行每行包含3或4个整数,代表两种操作之一( $i$ 为基于的历史版本号):

  1. 对于操作1,格式为 $v_i \ 1 \ {loc}_i \ {value}_i$ ,即为在版本 $v_i$ 的基础上,将 $a_{{loc}_i}$ 修改为 ${value}_i$​

  2. 对于操作2,格式为 $v_i \ 2 \ {loc}_i$ ,即访问版本 $v_i$ 中的 $a_{{loc}_i}$ 的值

输出格式:

输出包含若干行,依次为每个操作2的结果。

输入输出样例

输入样例#1:

  1. 5 10
  2. 59 46 14 87 41
  3. 0 2 1
  4. 0 1 1 14
  5. 0 1 1 57
  6. 0 1 1 88
  7. 4 2 4
  8. 0 2 5
  9. 0 2 4
  10. 4 2 1
  11. 2 2 2
  12. 1 1 5 91
输出样例#1:

  1. 59
  2. 87
  3. 41
  4. 87
  5. 88
  6. 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:

  1. //It is made by HolseLee on 5th Aug 2018
  2. //Luogu.org P3919
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cmath>
  7. #include<iostream>
  8. #include<iomanip>
  9. #include<algorithm>
  10. using namespace std;
  11.  
  12. const int N=1e6+;
  13. int n,m,root[N],a[N],cnt;
  14. struct node{
  15. int ls,rs,val;
  16. };
  17. struct Seg{
  18. node seg[N*];
  19.  
  20. inline void build(int &rt,int l,int r)
  21. {
  22. rt=++cnt;
  23. if(l==r){
  24. seg[rt].val=a[l];return;
  25. }
  26. int mid=(l+r)>>;
  27. build(seg[rt].ls,l,mid);
  28. build(seg[rt].rs,mid+,r);
  29. }
  30.  
  31. inline void update(int &rt,int last,int l,int r,int pos,int v)
  32. {
  33. rt=++cnt;
  34. seg[rt].ls=seg[last].ls,seg[rt].rs=seg[last].rs;
  35. seg[rt].val=seg[last].val;
  36. if(l==r){
  37. seg[rt].val=v;return;
  38. }
  39. int mid=(l+r)>>;
  40. if(pos<=mid)update(seg[rt].ls,seg[last].ls,l,mid,pos,v);
  41. else update(seg[rt].rs,seg[last].rs,mid+,r,pos,v);
  42. }
  43.  
  44. inline int quary(int rt,int l,int r,int pos)
  45. {
  46. if(l==r)return seg[rt].val;
  47. int mid=(l+r)>>;
  48. if(pos<=mid)return quary(seg[rt].ls,l,mid,pos);
  49. else return quary(seg[rt].rs,mid+,r,pos);
  50. }
  51. }T;
  52.  
  53. inline int read()
  54. {
  55. char ch=getchar();int num=;bool flag=false;
  56. while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
  57. while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
  58. return flag?-num:num;
  59. }
  60.  
  61. int main()
  62. {
  63. n=read();m=read();
  64. for(int i=;i<=n;++i)a[i]=read();
  65. T.build(root[],,n);
  66. int pre,pos,value,op;
  67. for(int i=;i<=m;++i){
  68. pre=read();op=read();pos=read();
  69. if(op==){
  70. T.update(root[i],root[pre],,n,pos,read());
  71. }
  72. else {
  73. printf("%d\n",T.quary(root[pre],,n,pos));
  74. root[i]=root[pre];
  75. }
  76. }
  77. return ;
  78. }

洛谷P3919 【模板】可持久化数组 [主席树]的更多相关文章

  1. P3919 (模板)可持久化数组 (主席树)

    题目链接 Solution 主席树水题,连差分的部分都不需要用到. 直接用主席树的结构去存一下就好了. Code #include<bits/stdc++.h> #define mid ( ...

  2. 【洛谷P3919】可持久化数组

    题目大意:需要维护一个长度为 N 的数组,支持在历史版本上单点修改和单点查询. 题解:显然,如果直接暴力维护的话会 MLE.因此,采用线段树进行维护,使得空间复杂度由 \(O(mn)\) 降至 \(O ...

  3. luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)

    luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include< ...

  4. 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]

    题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...

  5. 洛谷.3835.[模板]可持久化平衡树(fhq treap)

    题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...

  6. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  7. LOJ 2555 & 洛谷 P4602 [CTSC2018]混合果汁(二分+主席树)

    LOJ 题目链接 & 洛谷题目链接 题意:商店里有 \(n\) 杯果汁,第 \(i\) 杯果汁有美味度 \(d_i\),单价为 \(p_i\) 元/升.最多可以添加 \(l_i\) 升.有 \ ...

  8. 洛谷P2633 Count on a tree(主席树上树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  9. 洛谷P4587 [FJOI2016]神秘数(主席树)

    题面 洛谷 题解 考虑暴力,对于询问中的一段区间\([l,r]\),我们先将其中的数升序排序,假设当前可以表示出\([1,k]\)目前处理\(a_i\),假如\(a_i>k+1\),则答案就是\ ...

随机推荐

  1. [吴恩达机器学习笔记]12支持向量机5SVM参数细节

    12.支持向量机 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考资料 斯坦福大学 2014 机器学习教程中文笔记 by 黄海广 12.5 SVM参数细节 标记点选取 标记点(landma ...

  2. python---twisted的使用,使用其模拟Scrapy

    twisted的网络使用 twisted的异步使用 一:简单使用 from twisted.internet import defer from twisted.web.client import g ...

  3. HNOI2004 宠物收养所 (Treap)

    1285 宠物收养所 http://codevs.cn/problem/1285/  时间限制: 1 s  空间限制: 128000 KB     题目描述 Description 最近,阿Q开了一间 ...

  4. Python学习笔记(九)返回函数

    摘抄:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318352367 ...

  5. display:inline-block之用法

    HTML的元素有多种display属性,比较常见的有display:none; display:block; display:inline和display:inline-block;等.详细可参阅W3 ...

  6. DHTML中window的使用

    window对象是对浏览器窗口进行操作的对象.以下列出一些常用的对象(三级为对象的方法.属性) |-navigator:是对浏览器信息进行操作的对象 |-history:包含用户浏览过的url信息 | ...

  7. 【Foreign】减法 [二分][贪心]

    减法 Time Limit: 10 Sec  Memory Limit: 256 MB Description 给你一个n个数的序列A,并且给出m次操作B. 操作的含义是:每次从A中选出不同的B_i个 ...

  8. session_write_close()的作用

    简单地说,当开启session_start以后,这个session会一直开启,并且被一个用户使用.其他用户开启session的话要等待第一个session用户关闭以后才可以开启sessio,这样就造成 ...

  9. 组合数+逆元 A - Chat Group Gym - 101775A

    题目链接:https://cn.vjudge.net/contest/274151#problem/A 具体思路:我们可以先把所有的情况算出来,为2^n.然后不合法的情况减去就可以了.注意除法的时候要 ...

  10. 利用Jsoup模拟跳过登录爬虫获取数据

    今天在学习爬虫的时候想着学习一下利用jsoup模拟登录.下面分为有验证码和无验证码的情况进行讨论. ---------------------------无验证码的情况---------------- ...