题目大意:有两个操作,1:在第x次操作后的版本上修改一个值,2:查询在第x次操作后的版本上的一个节点的值

即:

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

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

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

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

题解:主席树,即针对每个询问建一棵线段树,但这样会MLE,不过我们可以发现由于相邻线段树的公共部分很多,可以充分利用,达到优化目的,同时每棵线段树还是保留所有的叶节点只是较之前共用了很多共用节点。每次修改最多增加O(log n)的空间,所以总的空间复杂度是O(n log n)

C++ Code:

#include<cstdio>
using namespace std;
const int maxn=20000100;
int root[1001000],lc[maxn],rc[maxn],val[maxn],cnt;
int n,m;
void build(int &rt,int l,int r){
rt=++cnt;
if (l==r){
scanf("%d",&val[rt]);
return;
}
int mid=l+r>>1;
build(lc[rt],l,mid);
build(rc[rt],mid+1,r);
}
void add(int &rt,int ver,int l,int r,int x,int y){
rt=++cnt;
lc[cnt]=lc[ver];rc[cnt]=rc[ver];
if (l==r){
val[rt]=y;
return;
}
int mid=l+r>>1;
if (x<=mid)add(lc[rt],lc[ver],l,mid,x,y);
else add(rc[rt],rc[ver],mid+1,r,x,y);
}
void ask(int rt,int l,int r,int x){
if (l==r){
printf("%d\n",val[rt]);
return;
}
int mid=l+r>>1;
if (x<=mid)ask(lc[rt],l,mid,x);
else ask(rc[rt],mid+1,r,x);
}
int main(){
scanf("%d%d",&n,&m);
build(root[0],1,n);
for (int i=1;i<=m;i++){
int num,ope,x,y;
scanf("%d%d",&num,&ope);
if (ope==1){
scanf("%d%d",&x,&y);
add(root[i],root[num],1,n,x,y);
}else{
scanf("%d",&x);
ask(root[num],1,n,x);
root[i]=root[num];
}
}
return 0;
}

最新文章

  1. MzBlog分析
  2. Nginx服务器之 Nginx的基本配置
  3. 关于js中的同步和异步
  4. 查看Eclipse版本
  5. 如何修改ubuntu系统的电脑名(主机名)
  6. LTRIM(str):返回 字符串str的前导(左边)空格字符去掉。
  7. peak num
  8. dfs.datanode.max.xcievers参数导致hbase集群报错
  9. Storm系列(七)架构分析之Scheduler-调度器[DefaultScheduler]
  10. linux管理员切换与管理员密码第一次设置
  11. Linux下区分物理CPU、逻辑CPU和CPU核数
  12. [2015-06-10 20:53:50 - Android SDK] Error when loading the SDK:
  13. Python更新pip出现错误解决方法
  14. JAVA代码规范笔记(上)
  15. Thymeleaf利用layout.html文件生成页面布局框架
  16. 关闭VS警告 warning C4996
  17. 利用远程服务器在docker容器搭建pyspider运行时出错的问题
  18. Array.sort()
  19. Good Bye 2018 C. New Year and the Sphere Transmission
  20. JavaScript-判断指定日期是一年中第几天-按照从大到小的顺序输出

热门文章

  1. js分割字符串
  2. git克隆出错 github clone Permission denied (publickey) fatal Could not read from remote repo
  3. 阿里云mysql连接不上
  4. (数据科学学习手札18)二次判别分析的原理简介&amp;Python与R实现
  5. 20145202马超 2006-2007-2 《Java程序设计》第3周学习总结
  6. C#的委托Delegate
  7. EAS集锦
  8. LeetCode:18. 4Sum(Medium)
  9. java基础 -- Collections.sort的两种用法
  10. 人工智能,图片识别,与GUI编程