博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
可持久化数组(可持久化线段树/平衡树)
阅读量:5357 次
发布时间:2019-06-15

本文共 2347 字,大约阅读时间需要 7 分钟。

题目背景

UPDATE : 最后一个点时间空间已经放大

标题即题意

有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集)

题目描述

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

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

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

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

输入输出格式

输入格式:

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

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

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

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

    {loc}_i} aloci​​​​ 修改为 valuei {value}_i valuei​​

  2. 对于操作2,格式为vi 2 loci v_i \ 2 \ {loc}_i vi​​ 2 loci​​,即访问版本vi v_i vi​​中的 aloci a_{
    {loc}_i} aloci​​​​的值
输出格式:

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

输入输出样例

输入样例#1:
5 1059 46 14 87 410 2 10 1 1 140 1 1 570 1 1 884 2 40 2 50 2 44 2 12 2 21 1 5 91
输出样例#1:
598741878846

主席树水题

用主席树维护一下每次数组的版本就行

1 #include
2 #include
3 #include
4 #include
5 using namespace std; 6 const int N=1000000; 7 struct Node 8 { 9 int val;10 Node *ch[2];11 }S[N*20],*pos=S;12 Node *root[N+5];13 int a[N+5],b[N+5],n,m,sz,rem[N+5];14 void build(Node* &rt,int l,int r)15 {16 rt=++pos;17 if (l==r) 18 {rt->val=a[l];19 return;20 }21 int mid=(l+r)/2;22 build(rt->ch[0],l,mid);23 build(rt->ch[1],mid+1,r);24 }25 void insert(Node* &rt,int l,int r,int k,int w)26 {27 Node *x=rt;28 rt=++pos;29 rt->ch[0]=x->ch[0];30 rt->ch[1]=x->ch[1];31 if (l==r) 32 {rt->val=w;33 return;34 }35 int mid=(l+r)/2;36 if (k<=mid) insert(rt->ch[0],l,mid,k,w);37 else insert(rt->ch[1],mid+1,r,k,w);38 }39 int query(Node* rt,int l,int r,int k)40 {41 if (l==r) return rt->val;42 int mid=(l+r)/2;43 if (mid>=k) return query(rt->ch[0],l,mid,k);44 else return query(rt->ch[1],mid+1,r,k);45 }46 int main()47 {
int i,j,x,y,k,p,v,w;48 cin>>n>>m;49 for (i=1;i<=n;i++)50 {51 scanf("%d",&a[i]);52 b[i]=a[i];53 }54 build(root[0],1,n);55 for (i=1;i<=m;i++)56 {57 scanf("%d%d",&p,&v);58 if (v==1)59 {60 scanf("%d%d",&k,&w);61 root[i]=root[p];62 insert(root[i],1,n,k,w);63 }64 else 65 {66 scanf("%d",&k);67 root[i]=root[p];68 printf("%d\n",query(root[i],1,n,k));69 }70 }71 }

 

转载于:https://www.cnblogs.com/Y-E-T-I/p/7629098.html

你可能感兴趣的文章
awk工具-解析1
查看>>
推荐一款可以直接下载浏览器sources资源的Chrome插件
查看>>
CRM product UI里assignment block的显示隐藏逻辑
查看>>
AMH V4.5 – 基于AMH4.2的第三方开发版
查看>>
Web.Config文件配置之配置Session变量的生命周期
查看>>
mysql导入source注意点
查看>>
linux下编译安装nginx
查看>>
ArcScene 高程不同的表面无法叠加
查看>>
[ONTAK2010] Peaks
查看>>
DLL 导出函数
查看>>
windows超过最大连接数解决命令
查看>>
12个大调都是什么
查看>>
angular、jquery、vue 的区别与联系
查看>>
javascript中sort()排序方法总结
查看>>
实现聊天界面的代码
查看>>
自己生成一个NDK的浅析
查看>>
Excel数据导入到数据库
查看>>
jQuery最佳实践
查看>>
SELinux FAQ
查看>>
Java中synchronized同步的理解
查看>>