可持久化线段树——区间更新hdu4348
和线段树类似,每个结点也要打lazy标记
但是lazy标记和线段树不一样
具体区别在于可持久化后lazy-tag不用往下传递,而是固定在这个区间并不断累加,变成了这个区间固有的性质(有点像分块的标记了)
update就按照这么来
int update(int last,int L,int R,int c,int l,int r){
int now=++size;
T[now]=T[last];
if(L<=l && R>=r){
T[now].sum+=(r-l+)*c;
T[now].add+=c;
return now;
}
int mid=l+r>>;
if(L<=mid)T[now].lc=update(T[last].lc,L,R,c,l,mid);
if(R>mid)T[now].rc=update(T[last].rc,L,R,c,mid+,r);
pushup(l,r,now);
return now;
}
查询时由于lazytag固定在区间上。所以向下查询的时候要把上层的lazytag的影响都算上,即递归时传递一个上层区间的 影响值(例如add)
ll query(int now,int L,int R,int add,int l,int r){
if(L<=l && R>=r) return T[now].sum+(ll)add*(r-l+);
int mid=l+r>>;
ll res=;add+=T[now].add;
if(L<=mid)res+=query(T[now].lc,L,R,add,l,mid);
if(R>mid)res+=query(T[now].rc,L,R,add,mid+,r);
return res;
}
此外还有合并维护时,由于子区间没有收到父区间的影响,所以合并时还要算父区间的lazytag
void pushup(int l,int r,int rt){T[rt].sum=T[T[rt].lc].sum+T[T[rt].rc].sum+T[rt].add*(r-l+);}
最后是完整代码,其实本题版本回滚时还可以吧size往回滚,以此节省内存
/*
主席树区间更新
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 100005
ll n,m,a[maxn];
struct Node{int lc,rc;ll sum,add;}T[maxn*];
int size,rt[maxn];
void pushup(int l,int r,int rt){T[rt].sum=T[T[rt].lc].sum+T[T[rt].rc].sum+T[rt].add*(r-l+);}
int build(int l,int r){
int now=++size;
if(l==r){
T[now].lc=T[now].rc=;
T[now].sum=a[l];
return now;
}
int mid=l+r>>;
T[now].lc=build(l,mid);
T[now].rc=build(mid+,r);
pushup(l,r,now);
return now;
}
int update(int last,int L,int R,int c,int l,int r){
int now=++size;
T[now]=T[last]; if(L<=l && R>=r){
T[now].sum+=(r-l+)*c;
T[now].add+=c;
return now;
} int mid=l+r>>;
if(L<=mid)T[now].lc=update(T[last].lc,L,R,c,l,mid);
if(R>mid)T[now].rc=update(T[last].rc,L,R,c,mid+,r);
pushup(l,r,now);
return now;
}
ll query(int now,int L,int R,int add,int l,int r){
if(L<=l && R>=r) return T[now].sum+(ll)add*(r-l+);
int mid=l+r>>;
ll res=;add+=T[now].add;
if(L<=mid)res+=query(T[now].lc,L,R,add,l,mid);
if(R>mid)res+=query(T[now].rc,L,R,add,mid+,r);
return res;
}
void init(){
size=;
memset(rt,,sizeof rt);
memset(T,,sizeof T);
}
int main(){
while(scanf("%lld%lld",&n,&m)==){
init();
for(int i=;i<=n;i++)scanf("%lld",&a[i]); int cur=,l,r,c;char op[];
rt[cur]=build(,n);
while(m--){
scanf("%s",op);
if(op[]=='C'){scanf("%d%d%d",&l,&r,&c);rt[++cur]=update(rt[cur-],l,r,c,,n);}
if(op[]=='Q'){scanf("%d%d",&l,&r);cout<<query(rt[cur],l,r,,,n)<<'\n';}
if(op[]=='H'){
scanf("%d%d%d",&l,&r,&c);
cout<<query(rt[c],l,r,,,n)<<'\n';
}
if(op[]=='B'){scanf("%d",&c);cur=c;}
}
// puts("");
}
}
可持久化线段树——区间更新hdu4348的更多相关文章
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- HDU 1556 Color the ball(线段树区间更新)
Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
- hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新
#1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...
- HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...
- HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...
- HDU 1698 线段树 区间更新求和
一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...
- POJ-2528 Mayor's posters (线段树区间更新+离散化)
题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...
- ZOJ 1610 Count the Colors (线段树区间更新)
题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...
- POJ 2528 Mayor's posters (线段树区间更新+离散化)
题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...
随机推荐
- C#中声明、调用和配置事件的演示源码
下面的内容是关于C#中声明.调用和配置事件的演示的内容,应该能对大伙有些好处. using System;namespace MyCollections { using System.Collecti ...
- git的命令行输出正确地显示中文文件名
参考:https://stackoverflow.com/questions/22827239/how-to-make-git-properly-display-utf-8-encoded-pathn ...
- DP的优化总结
一.预备知识 \(tD/eD\) 问题:状态 t 维,决策 e 维.时间复杂度\(O(n^{e+t})\). 四边形不等式: 称代价函数 w 满足凸四边形不等式,当:\(w(a,c)+w(b,d)\l ...
- jQuery与原生JS相互转化
前端发展很快,现代浏览器原生 API 已经足够好用.我们并不需要为了操作 DOM.Event 等再学习一下 jQuery 的 API.同时由于 React.Angular.Vue 等框架的流行,直接操 ...
- Vue针对性笔记
Github原文阅读 MVVM(Model-View-ViewModel)模型 MVVM分为Model.View.ViewModel三部分. Model代表数据模型,定义数据和业务逻辑,访问数据层 V ...
- CF 1145 (愚人节比赛)
D题 题目就是让你找出题面中拼错的单词,拼错的字母组合成一句话就是正确的题面. two plus xor of third and min elements #include<bits/stdc ...
- 【Linux】Jenkins安装
安装环境准备 操作系统:Linux(CentOS7) 软件:jdk,安装及配置步骤见Linux安装jdk 软件:tomcat,安装及配置见Linux安装tomcat Jenkins安装 由于Jenki ...
- 微信公众号开发之access_token的全局共用
最近做微信公众号开发,涉及到access_token的缓存问题(避免各自的应用都去取access_token,同时解决微信 appid和appsecret的安全问题),在通用权限管理系统底层增加了实现 ...
- J.U.C-volatile
禁止指令重排
- 077、跨主机使用Rex-Ray volume (2019-04-24 周三)
参考https://www.cnblogs.com/CloudMan6/p/7630205.html 上一节我们在docker1上创建mysql容器,并使用了 Rex-Ray volume mys ...