【CJOJ2316】【模板】可持久化线段树
题面
Description
这是一道非常直白的可持久化线段树的练习题,目的并不是虐人,而是指导你入门可持久化数据结构。
线段树有个非常经典的应用是处理RMQ问题,即区间最大/最小值询问问题。现在我们把这个问题可持久化一下:
Q k l r 查询数列在第k个版本时,区间[l, r]上的最大值
M k p v 把数列在第k个版本时的第p个数修改为v,并产生一个新的数列版本
最开始会给你一个数列,作为第1个版本。
每次M操作会导致产生一个新的版本。修改操作可能会很多呢,如果每次都记录一个新的数列,空间和时间上都是令人无法承受的。所以我们需要可持久化数据结构:
对于最开始的版本1,我们直接建立一颗线段树,维护区间最大值。
修改操作呢?我们发现,修改只会涉及从线段树树根到目标点上一条树链上logn个节点而已,其余的节点并不会受到影响。所以对于每次修改操作,我们可以只重建修改涉及的节点即可。就像这样:
P
需要查询第k个版本的最大值,那就从第k个版本的树根开始,像查询普通的线段树一样查询即可。
Input
第一行两个整数N, Q。N是数列的长度,Q表示询问数
第二行N个整数,是这个数列
之后Q行,每行以0或者1开头,0表示查询操作Q,1表示修改操作M,格式为
0 k l r 查询数列在第k个版本时,区间[l, r]上的最大值 或者
1 k p v 把数列在第k个版本时的第p个数修改为v,并产生一个新的数列版本
Output
对于每个M询问,输出正确答案
Sample Input
4 5
1 2 3 4
0 1 1 4
1 1 3 5
0 2 1 3
0 2 4 4
0 1 2 4
Sample Output
4
5
4
4
Hint
样例解释:
序列版本1: 1 2 3 4
查询版本1的[1, 4]最大值为4
修改产生版本2: 1 2 5 4
查询版本2的[1, 3]最大值为5
查询版本1的[4, 4]最大值为4
查询版本1的[2, 4]最大值为4
N <= 10000 Q <= 100000
对于每次询问操作的版本号k保证合法,
区间[l, r]一定满足1 <= l <= r <= N
Source
原题见: http://syzoj.com/problem/247
可持久化线段树
题解
主席树板子题
自己YY了一晚上弄出来了
到时候再写主席树的东西吧。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX 1000000
#define ll long long
inline int read()
{
register int x=0,t=1;
register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-'){t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*t;
}
struct Node//线段树节点
{
int ch[2];//左儿子和右儿子
int l,r;//左节点右节点
int val;//最大值
}c[MAX];
int n,Q,a[MAX],cnt,Root[MAX];
void Build(int now,int l,int r)//构建第一版本的线段树
{
++cnt;
c[now].l=l;c[now].r=r;
if(l==r){c[now].val=a[l];return;}
int mid=(l+r)>>1;
c[now].ch[0]=cnt+1;
Build(cnt+1,l,mid);
c[now].ch[1]=cnt+1;
Build(cnt+1,mid+1,r);
c[now].val=max(c[c[now].ch[0]].val,c[c[now].ch[1]].val);
}
int Query(int now,int al,int ar)//查询最大值
{
int l=c[now].l,r=c[now].r;
if(l==al&&ar==r)return c[now].val;
int lson=c[now].ch[0],rson=c[now].ch[1];
int mid=(l+r)>>1;
if(ar<=mid)return Query(lson,al,ar);
if(al>mid)return Query(rson,al,ar);
return max(Query(lson,al,mid),Query(rson,mid+1,ar));
}
void Update(int now,int k,int x)
{
++cnt;int tt=cnt;
c[cnt]=c[now];//直接复制要更新的节点
int l=c[now].l,r=c[now].r;
if(l==r){c[cnt].val=x;return;}
int mid=(l+r)>>1;
if(k<=mid){c[tt].ch[0]=cnt+1;Update(c[now].ch[0],k,x);}
else{c[tt].ch[1]=cnt+1;Update(c[now].ch[1],k,x);}
c[tt].val=max(c[c[tt].ch[0]].val,c[c[tt].ch[1]].val);
}
int main()
{
n=read();Q=read();
for(int i=1;i<=n;++i)a[i]=read();
Build(1,1,n);Root[1]=1;
int Ver=1;
while(Q--)
{
int tt=read(),k=read(),L=read(),R=read();
if(tt==0)
printf("%d\n",Query(Root[k],L,R));
else
{
Root[++Ver]=cnt+1;//当前新版本的根节点
Update(Root[k],L,R);
}
}
}
【CJOJ2316】【模板】可持久化线段树的更多相关文章
- 【洛谷P3834】(模板)可持久化线段树 1(主席树)
[模板]可持久化线段树 1(主席树) https://www.luogu.org/problemnew/show/P3834 主席树支持历史查询,空间复杂度为O(nlogn),需要动态开点 本题用一个 ...
- 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]
题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...
- 洛谷.3834.[模板]可持久化线段树(主席树 静态区间第k小)
题目链接 //离散化后范围1~cnt不要错 #include<cstdio> #include<cctype> #include<algorithm> //#def ...
- [学习笔记] 可持久化线段树&主席树
众所周知,线段树是一个非常好用也好写的数据结构, 因此,我们今天的前置技能:线段树. 然而,可持久化到底是什么东西? 别急,我们一步一步来... step 1 首先,一道简化的模型: 给定一个长度为\ ...
- Luogu P3919 【模板】可持久化数组 可持久化线段树
其实就是可持久化线段树的模板题线段树不会看这里 #include<bits/stdc++.h> ; using namespace std; ]; ],rc[N*],val[N*],cnt ...
- LuoguP3834 【模板】可持久化线段树 1(主席树)|| 离散化
题目:[模板]可持久化线段树 1(主席树) 不知道说啥. #include<cstdio> #include<cstring> #include<iostream> ...
- Luogu P3919【模板】可持久化数组(可持久化线段树/平衡树)
题面:[模板]可持久化数组(可持久化线段树/平衡树) 不知道说啥,总之我挺喜欢自己打的板子的! #include<cstdio> #include<cstring> #incl ...
- 洛谷 P3919 【模板】可持久化数组(可持久化线段树/平衡树)-可持久化线段树(单点更新,单点查询)
P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...
- 洛谷——P3919 【模板】可持久化数组(可持久化线段树/平衡树)
P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...
随机推荐
- 关于一些php规范
<?php /** * 符合psr-1,2的编程实例 * * @author GreenForestQuan */ namespace Standard; // 顶部命名空间 // 空一行 us ...
- LeetCode - 520. Detect Capital
Given a word, you need to judge whether the usage of capitals in it is right or not. We define the u ...
- Quartz动态改变任务时间
基于quartz-2.2 的动态任务调度 Quartz是一个完全由java编写的开源作业调度框架. 调度器 Quartz框架的核心是调度器.调度器负责管理Quartz应用运行时环境.调度器不是靠自己做 ...
- JDBCTemplate与模板设计方法(二)
前言:上一篇博客介绍了模板方法模式,并且给出了一个小demo,简单对模板方法进行了实现,接下来我们把目光转向spring的源码JDBCTemplate,看一看spring是如何对jdbc进行高度封装的 ...
- LINUX下的U盘挂载
linux下如果没有图形界面的情况下就要我们自己熟悉命令来挂载U盘,下面给大家详细描述下U盘的挂载过程. 1. 插入U盘 2. #sudo fdisk –l 查看所挂载盘符名称如下图,假设盘符名称为s ...
- Zabbix 3.0 监控Web
zabbix 界面配置 触发器添加
- 8、flask之flask-script组件
Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他运行在web应用之外的命令行任 ...
- 1.2 decimal模块
>>> 0.1 + 0.1 +0.1 == 0.3 False >>> >>> print(0.1 + 0.1 + 0.1) 0.30000000 ...
- 3D打印技术在医疗上的实际应用与实验室研究
2018-01-17 Chris 免费3D打印模型资源站 预计阅读时间:5-10分钟 关键字:3D打印髋关节.脊柱置换产品,3D打印技术辅助精准截骨,义齿,生物墨水(BioInk),干细胞 随着& ...
- mysql打不开表问题解决方案
做开发时候某一表怎么也打不开,数据也不多,网上查了按下面这篇文章完美解决,但是要记得用root登录mysql: 记一次MySQL中Waiting for table metadata lock的解决方 ...