[学习笔记]标记永久化
线段树出了名的操作是lazy标记。
普通lazy标记涉及到pushup和pushdown
这个pushup只涉及两个儿子合并,并且两个儿子是两个点。
但是有的时候,两个儿子是两个树,pushup复杂度就爆炸了。
给你一个线段树的树套树,外层的线段树pushup一下,就对应里面每个节点对应pushup。O(n^2log^2n)优秀数据结构诞生辣
还有的时候,主席树要区间修改。
每次修改操作我们在之前基础上建一棵新树,问题是,儿子是共用的,pushdown一下,之前的版本也会受到影响。凉凉。
所以要标记永久化。
标记永久化,就是标记不用pushdown,自然也不用pushup(开始建树的时候,可能要pushup)
以一维线段树区间加,区间求和为例。
add懒标记,sum是和。
upda时候,路上的sum都加上c*len;如果到了该返回的完全包含节点时候,再把add加上c。
query的时候,把路上的add都做和,到了该返回的节点的时候,返回sum[x]+addsum*len(注意这一层的add别加了就)
可以发现,一路统计,一路标记下来,add,sum有机配合,就可以算出了。
可以理解为,query的时候,在x节点的父亲做过的赋值用add求了出来,x子孙做过的赋值sum已经处理完毕。所以没有问题。
真正的例子:
[POI2006]TET-Tetris 3D
二维线段树,矩形求max,矩形取max
(ps:这个题不是矩形取max的话,如果是矩形赋值,标记永久化还真做不了。。)
外层行,内层列。
对于外层的线段树,这个是不能懒标记的。
类比上面开两个变量,这里我们开两个树。
一个mx树,节点上的内层线段树记录这若干行压缩起来的最大值
一个tag树,节点上。。。。。。。。。。。。所打标记的最大值
然后update,query类比即可 。
内层线段树由于儿子就是两个点,所以随意了。
代码:(空间玄学,反正卡着边界能过)
#include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') #define mid ((l+r)>>1) using namespace std; typedef long long ll; il void rd(int &x){char ch;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x); } namespace Miracle{ const int N=1050; int n,m,k; struct node{int ans[2*N],laz[2*N];void upda(int x,int l,int r,int L,int R,int c){ans[x]=max(ans[x],c);if(L<=l&&r<=R) {laz[x]=max(laz[x],c);return;}if(L<=mid) upda(x<<1,l,mid,L,R,c);if(mid<R) upda(x<<1|1,mid+1,r,L,R,c);}int query(int x,int l,int r,int L,int R){if(L<=l&&r<=R){return ans[x];}int ret=laz[x];if(L<=mid) ret=max(ret,query(x<<1,l,mid,L,R));if(mid<R) ret=max(ret,query(x<<1|1,mid+1,r,L,R));return ret;} }mx[2*N],tag[2*N]; void upda(int x,int l,int r,int l1,int r1,int l2,int r2,int c){mx[x].upda(1,1,m,l2,r2,c);if(l1<=l&&r<=r1){tag[x].upda(1,1,m,l2,r2,c);return;}if(l1<=mid) upda(x<<1,l,mid,l1,r1,l2,r2,c);if(mid<r1) upda(x<<1|1,mid+1,r,l1,r1,l2,r2,c); } int query(int x,int l,int r,int l1,int r1,int l2,int r2){if(l1<=l&&r<=r1) return mx[x].query(1,1,m,l2,r2);int ret=tag[x].query(1,1,m,l2,r2);if(l1<=mid) ret=max(ret,query(x<<1,l,mid,l1,r1,l2,r2));if(mid<r1) ret=max(ret,query(x<<1|1,mid+1,r,l1,r1,l2,r2));return ret; } int main(){rd(n);rd(m);rd(k);int x,y,s,d,h;while(k--){rd(d);rd(s);rd(h);rd(x);rd(y);++x,++y;int ch=query(1,1,n,x,x+d-1,y,y+s-1)+h;upda(1,1,n,x,x+d-1,y,y+s-1,ch);}printf("%d",query(1,1,n,1,n,1,m));return 0; }} signed main(){Miracle::main();return 0; }/*Author: *Miracle*Date: 2018/12/9 18:33:23 */
ps:感觉如果值不具有覆盖性(取max)或者等价撤销性(加减),就不能标记永久化了(赋值)
转载于:https://www.cnblogs.com/Miracevin/p/10092806.html
[学习笔记]标记永久化相关推荐
- OpenCV for Ios 学习笔记(4)-标记检测1
本文原始地址:OpenCV for Ios 学习笔记(4)-标记检测1 简单的标记经常是以白色块和黑色块构成的规则图形.因为我们预先知道这些因素,所以我们可以很容易检测标记. 如图: 首先,我们需要找 ...
- 【EF学习笔记09】----------使用 EntityState 枚举标记实体状态,实现增删改查
[EF学习笔记09]----------使用 EntityState 枚举标记实体状态,实现增删改查 讲解之前,先来看一下我们的数据库结构:班级表 学生表 如上图,实体状态由EntityState枚举 ...
- JVM学习笔记之四 四种引用和垃圾回收的两次标记
四种引用和两次标记 四种引用 java中的数据类型我们知道是分为基本数据类型和引用类型的.基本数据类型是8种,分别是boolean byte short int long double float c ...
- oracle查询数据做标记,【学习笔记】Oracle如何使用dbms_shared_pool.markhot标记热对象...
[学习笔记]Oracle如何使用dbms_shared_pool.markhot标记热对象 时间:2016-10-30 20:17 来源:Oracle研究中心 作者:HTZ 点击: 次 天 ...
- 知识图谱学习笔记(1)
知识图谱学习笔记第一部分,包含RDF介绍,以及Jena RDF API使用 知识图谱的基石:RDF RDF(Resource Description Framework),即资源描述框架,其本质是一个 ...
- SVO中 Inverse Compositional Image Alignment方法的学习笔记
SVO中 Inverse Compositional Image Alignment方法的学习笔记 这篇文章 光流法简介 逆向光流法 结尾 这篇文章 在SVO系统中的"Relaxation ...
- SVO学习笔记(二)
SVO学习笔记(二) 这篇文章 稀疏图像对齐 地图点投影(地图与当前帧间的关系) reprojectMap reprojectPoint reprojectCell 特征点对齐中的非线性优化 结尾 这 ...
- Json.Net学习笔记
Json.Net学习笔记 摘自: http://www.verydemo.com/demo_c360_i45119.html 分类: 编程语言/ ASP.NET/ 文章 导读:string goog ...
- AI学习笔记之——如何理解机器学习(Machine Learning)
前面虽然介绍了概率和贝叶斯网络,但是还是没有正式介绍AI中最重要的算法--机器学习.如果说概率论是机器学习的基石,那么机器学习算法和理论就是支撑整个AI系统的支柱.现在比较火的深度学习神经网路等等其实 ...
最新文章
- 别在迷恋正则表达式解析html了,好吗?
- node实战学习纪录
- Qt webkitwidgets模块和webenginewidgets模块
- Python之collections容器数据类型
- 30分钟,让你成为一个更好的程序员
- java media.player_关于Java:如何正确发布Android MediaPlayer
- ListBox和ComboBox绑定数据简单例子
- Windows三十年进化史,从Windows 1.0到Windows 10
- 如何解决无法显示隐藏文件文件夹
- c# Linq Where 抛出异常 导致 程序崩溃
- c 语言随机验证码原理,用C生成随机中文汉字验证码的基本原理及代码.doc
- [Git] warning: Clone succeeded, but checkout failed.
- 两岁的微信小程序,创造超 5000 亿的价值
- java -1%3_java学习笔记(day23)
- 云服务器的带宽是如何计算的?
- 【EJB基础】开发一个简单的EJB应用程序
- golang copy-on-write思想应用
- Redhat 8 制作本地光盘镜像yum源
- 奇迹 与服务器连接中断,奇迹少女连接服务器失败 连接不上网络怎么办
- 监督和无监督、分类和回归算法总结
热门文章
- repository access denied. access via a deployment key is read-only.
- 牛客网Java刷题知识点之数组、链表、哈希表、 红黑二叉树
- Oracle 客户端库时引发 BadImageFormatException
- ZF1.* 愤怒小鸟系列二:快速自定义创建MVC
- SQLServer 2000 生成数据源的SQL脚本
- asp.net 研发,测试,或现网....非本机环境采用附加进程的方式在本地调试
- sniffer 工具
- onvirt安装linux系统
- 06jQuery-01-基本选择器
- jstl与struts2 条件语句的区别