UOJ#164:【清华集训2015】V
浅谈区间最值操作与历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html
题目传送门:http://uoj.ac/problem/164
论文题。论文做法如下:
首先我们定义一种标记\((a,b)\),表示给这个区间先加上\(a\)再跟\(b\)取\(max\),不难发现题目里提到的三种操作分别都可以用这样的标记来代替:
1、区间加\(v\):\((v,-inf)\)
2、区间减\(v\):\((-v,0)\)
3、区间覆盖:\((-inf,v)\)
考虑合并两个标记\((a,b),(c,d)\),那么就会变成\((a+c,max(b+c,d))\)。
现在考虑历史标记最大值,对于一个标记,我们可以将它看成是一个分段函数。第一段的函数是\(y=b\),第二段的函数是\(y=x+a\)。那么历史最大标记则可以用\((max(a,c),max(b,d))\)来表示。如下图,红色的部分就是历史标记最大值:

时间复杂度:\(O(nlogn)\)
空间复杂度:\(O(n)\)
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll inf=1e18;
const int maxn=5e5+5;
int n,m;
int a[maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct segment_tree {
struct tag {
ll add,mx;
void init() {
add=0,mx=-inf;
}
tag() {}
tag(ll _add,ll _mx) {
add=_add,mx=_mx;
}
tag operator+(const tag &a)const {
return tag(max(-inf,add+a.add),max(mx+a.add,a.mx));
}
tag operator*(const tag &a)const {
return tag(max(add,a.add),max(mx,a.mx));
}
};
struct tree_node {
ll hismx,mx;
tag his,now;
}tree[maxn<<2];
void update(int p) {
tree[p].mx=max(tree[p<<1].mx,tree[p<<1|1].mx);
tree[p].hismx=max(tree[p<<1].hismx,tree[p<<1|1].hismx);
}
void build(int p,int l,int r) {
tree[p].his.init(),tree[p].now.init();
if(l==r) {tree[p].hismx=tree[p].mx=a[l];return;}
int mid=(l+r)>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
update(p);
}
void make_tag(int p,tag now,tag his) {
tree[p].his=tree[p].his*(tree[p].now+his);
tree[p].now=tree[p].now+now;
ll res=max(tree[p].mx+his.add,his.mx);
tree[p].hismx=max(tree[p].hismx,res);
tree[p].mx=max(tree[p].mx+now.add,now.mx);
}
void push_down(int p) {
make_tag(p<<1,tree[p].now,tree[p].his);
make_tag(p<<1|1,tree[p].now,tree[p].his);
tree[p].now.init(),tree[p].his.init();
}
void change(int p,int l,int r,int L,int R,ll v,ll mx) {
if(L<=l&&r<=R) {make_tag(p,tag(v,mx),tag(v,mx));return;}
int mid=(l+r)>>1;push_down(p);
if(L<=mid)change(p<<1,l,mid,L,R,v,mx);
if(R>mid)change(p<<1|1,mid+1,r,L,R,v,mx);
update(p);
}
ll query(int p,int l,int r,int pos,int opt) {
if(l==r) return opt==4?tree[p].mx:tree[p].hismx;
int mid=(l+r)>>1;push_down(p);
if(pos<=mid)return query(p<<1,l,mid,pos,opt);
else return query(p<<1|1,mid+1,r,pos,opt);
}
}T;
int main() {
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
T.build(1,1,n);
for(int i=1;i<=m;i++) {
int opt=read(),l=0,r=0,v=0,pos=0;
if(opt>3)pos=read();
else l=read(),r=read(),v=read();
if(opt==1)T.change(1,1,n,l,r,v,-inf);
if(opt==2)T.change(1,1,n,l,r,-v,0);
if(opt==3)T.change(1,1,n,l,r,-inf,v);
if(opt>3)printf("%lld\n",T.query(1,1,n,pos,opt));
}
return 0;
}
UOJ#164:【清华集训2015】V的更多相关文章
- UOJ #164 [清华集训2015]V (线段树)
题目链接 http://uoj.ac/problem/164 题解 神仙线段树题. 首先赋值操作可以等价于减掉正无穷再加上\(x\). 假设某个位置从前到后的操作序列是: \(x_1,x_2,..., ...
- 清华集训2015 V
#164. [清华集训2015]V http://uoj.ac/problem/164 统计 描述 提交 自定义测试 Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...
- 【uoj#164】[清华集训2015]V 线段树维护历史最值
题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...
- 「清华集训2015」V
「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...
- [UOJ#274][清华集训2016]温暖会指引我们前行
[UOJ#274][清华集训2016]温暖会指引我们前行 试题描述 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一 ...
- UOJ #164. 【清华集训2015】V | 线段树
题目链接 UOJ #164 题解 首先,这道题有三种询问:区间加.区间减(减完对\(0\)取\(\max\)).区间修改. 可以用一种标记来表示--标记\((a, b)\)表示把原来的值加上\(a\) ...
- 2018.07.28 uoj#164. 【清华集训2015】V(线段树)
传送门 线段树好题. 要求支持的操作: 1.区间变成max(xi−a,0)" role="presentation" style="position: rela ...
- UOJ #164 【清华集训2015】 V
题目链接:V 这道题由于是单点询问,所以异常好写. 注意到每种修改操作都可以用一个标记\((a,b)\)表示.标记\((a,b)\)的意义就是\(x= \max\{x+a,b\}\) 同时这种标记也是 ...
- @uoj - 164@ 【清华集训2015】V
目录 @description@ @solution@ @accepted code@ @details@ @description@ Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化 ...
随机推荐
- Computer Transformation(简单数学题+大数)
H - Computer Transformation Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d &am ...
- ArcGIS Scalebar 比例尺 充满div
说明:本篇博文地图充满div,上一篇博文是充满整个body 运行效果: 2.HTML代码 <!DOCTYPE html> <html> <head> <met ...
- 测试站如何最快获取正式站的最新数据: ln -s
针对静态数据, 比如图片/js等文件, 测试站如何获取最新的呢? ln -s /alidata/www/mysite/uploads /alidata/www/mysite_test/uploads ...
- 12.Django数据库操作(执行原生SQL)
1.使用extra方法 解释:结果集修改器,一种提供额外查询参数的机制 说明:依赖model模型 用在where后: Book.objects.filter(publisher_id="1& ...
- jQuery:[1]实现图片上传并预览
jQuery:[1]实现图片上传并预览 原理 预览思路 1.当上传对象的input被触发并选择本地图片之后获取要上传的图片对象的URL: 2.把对象URL赋值给实现写好的img标签的src属性 Fil ...
- 让你快速上手Runtime(转)
前言 本篇主要介绍Runtime在开发中的一些使用场景,顺便讲解了下MJExtension的底层实现.如果喜欢我的文章,可以关注我微博:袁峥Seemygo,也可以来小码哥,了解下我们的iOS培训课程. ...
- [原创] hadoop学习笔记:重新格式化HDFS文件系统
所谓的重新格式化HDFS文件系统,实际意味着重新的创建一个HDFS文件系统.也就是说,必须将先前的已经有的文件系统配置删除.如下: 笔者采用的是最小化安装 这个是core-site.xml配置 这个是 ...
- 20145229吴姗珊 《Java程序设计》第3周学习总结
20145229吴姗珊 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 认识对象 4.1类与对象 1.对象(Object):存在的具体实体,具有明确的状态和行为 2.类(Cl ...
- HDU 2736 Surprising Strings
Surprising Strings Time Limit:1000MS Memory Limit:65536KB 64 ...
- 什么是shell【TLCL】
常用命令 date cal df——report file system disk space usage free——display amount of free and used memory i ...