2018.07.28 uoj#164. 【清华集训2015】V(线段树)
传送门
线段树好题。
要求支持的操作:
1.区间变成max(xi−a,0)" role="presentation" style="position: relative;">max(xi−a,0)max(xi−a,0)
2.区间加
3.区间覆盖
4.询问单点最值
5.询问单点历史最值
注:以下提到的标记都是向下传递的懒标记。
这题直接更新区间最大值貌似不好维护,因此我们需要更换思路,对于每个节点维护一个标记(a,b)" role="presentation" style="position: relative;">(a,b)(a,b),来表示在上一次修改这个区间之后当前区间的所有数都变成(xi+a,b)" role="presentation" style="position: relative;">(xi+a,b)(xi+a,b),这样的话,第一个操作变成了(−a,0)" role="presentation" style="position: relative;">(−a,0)(−a,0),第二个操作变成了(a,−inf)" role="presentation" style="position: relative;">(a,−inf)(a,−inf),第三个操作变成了(−inf,a)" role="presentation" style="position: relative;">(−inf,a)(−inf,a)。然后查询的时候只用查询单点的(a,b)" role="presentation" style="position: relative;">(a,b)(a,b),然后输出(xi+a,b)" role="presentation" style="position: relative;">(xi+a,b)(xi+a,b)的较大值就行了。
然后我们考虑这个标记如何合并,假设现在已经有了一个标记(a,b)" role="presentation" style="position: relative;">(a,b)(a,b),从父亲节点传过来了一个标记(c,d)" role="presentation" style="position: relative;">(c,d)(c,d),那么原本这个点的最大值是max(xi+a,b)" role="presentation" style="position: relative;">max(xi+a,b)max(xi+a,b),现在就变成了max(max(xi+a,b)+c,d)" role="presentation" style="position: relative;">max(max(xi+a,b)+c,d)max(max(xi+a,b)+c,d),也就是max(xi+a+b,b+c,d)" role="presentation" style="position: relative;">max(xi+a+b,b+c,d)max(xi+a+b,b+c,d),也就是max(xi+a+b,max(b+c,d))" role="presentation" style="position: relative;">max(xi+a+b,max(b+c,d))max(xi+a+b,max(b+c,d)),所以这个节点的标记就被更新成了(a+b,max(b+c,d))" role="presentation" style="position: relative;">(a+b,max(b+c,d))(a+b,max(b+c,d))。所以这个标记是可合并的。
然而,我们仍然不能够维护历史单点最大值,因此我们还需要维护一个(hisa,hisb)" role="presentation" style="position: relative;">(hisa,hisb)(hisa,hisb)标记,表示在上一次修改这个区间之后xi" role="presentation" style="position: relative;">xixi最大的历史增量和最大的历史取max" role="presentation" style="position: relative;">maxmax标记,最后同样是查询单点的(hisa,hisb)" role="presentation" style="position: relative;">(hisa,hisb)(hisa,hisb),然后输出(xi+hisa,hisb)" role="presentation" style="position: relative;">(xi+hisa,hisb)(xi+hisa,hisb)的较大值。
这时我们应该大胆的猜想一个节点的history" role="presentation" style="position: relative;">historyhistory标记也是可以合并的。仔细想想,如果从父亲节点传来了一个(a,b,hisa,hisb)" role="presentation" style="position: relative;">(a,b,hisa,hisb)(a,b,hisa,hisb),那么显然是用父亲的hisa" role="presentation" style="position: relative;">hisahisa和自己的a" role="presentation" style="position: relative;">aa来更新自己的hisa" role="presentation" style="position: relative;">hisahisa,然后用父亲的hisa" role="presentation" style="position: relative;">hisahisa和自己的b" role="presentation" style="position: relative;">bb,以及父亲的hisb" role="presentation" style="position: relative;">hisbhisb来更新自己的hisb" role="presentation" style="position: relative;">hisbhisb。
也就是hisa=max(hisa,fa.hisa+a),hisb=max(hisb,max(fa.hisb,fa.hisa+b))" role="presentation" style="position: relative;">hisa=max(hisa,fa.hisa+a),hisb=max(hisb,max(fa.hisb,fa.hisa+b))hisa=max(hisa,fa.hisa+a),hisb=max(hisb,max(fa.hisb,fa.hisa+b))
代码:
#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
#define inf 1000000000000000000
#define N 500005
#define ll long long
using namespace std;
int n,m,op,l,r;
ll a[N],v;
struct Node{int l,r;ll a,b,his_a,his_b;}T[N<<2];
inline ll max(ll a,ll b){return a>b?a:b;}
inline void operator+=(Node&x,Node y){
x.his_a=max(x.his_a,y.his_a+x.a);
x.his_b=max(x.his_b,max(x.b+y.his_a,y.his_b));
x.a=max(x.a+y.a,-inf);
x.b=max(x.b+y.a,y.b);
}
inline void cle(int p){T[p].his_a=T[p].a=0,T[p].his_b=T[p].b=-inf;}
inline void pushdown(int p){T[lc]+=T[p],T[rc]+=T[p],cle(p);}
inline void build(int p,int l,int r){
T[p].l=l,T[p].r=r,cle(p);
if(l==r)return;
build(lc,l,mid),build(rc,mid+1,r);
}
inline void update(int p,int ql,int qr,Node v){
if(ql>T[p].r||qr<T[p].l)return;
if(ql<=T[p].l&&T[p].r<=qr){T[p]+=v;return;}
if(T[p].l!=T[p].r)pushdown(p);
if(qr<=mid)update(lc,ql,qr,v);
else if(ql>mid)update(rc,ql,qr,v);
else update(lc,ql,mid,v),update(rc,mid+1,qr,v);
}
inline Node query(int p,int k){
if(T[p].l==T[p].r)return T[p];
pushdown(p);
if(k<=mid)return query(lc,k);
return query(rc,k);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
build(1,1,n);
while(m--){
scanf("%d",&op);
if(op==1)scanf("%d%d%lld",&l,&r,&v),update(1,l,r,(Node){l,r,v,-inf,v,-inf});
if(op==2)scanf("%d%d%lld",&l,&r,&v),update(1,l,r,(Node){l,r,-v,0,-v,0});
if(op==3)scanf("%d%d%lld",&l,&r,&v),update(1,l,r,(Node){l,r,-inf,v,-inf,v});
if(op==4){scanf("%d",&l);Node t=query(1,l);printf("%lld\n",max(a[l]+t.a,t.b));}
if(op==5){scanf("%d",&l);Node t=query(1,l);printf("%lld\n",max(a[l]+t.his_a,t.his_b));}
}
return 0;
}
2018.07.28 uoj#164. 【清华集训2015】V(线段树)的更多相关文章
- UOJ #164 [清华集训2015]V (线段树)
题目链接 http://uoj.ac/problem/164 题解 神仙线段树题. 首先赋值操作可以等价于减掉正无穷再加上\(x\). 假设某个位置从前到后的操作序列是: \(x_1,x_2,..., ...
- 【uoj#164】[清华集训2015]V 线段树维护历史最值
题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...
- 【题解】P4247 [清华集训]序列操作(线段树修改DP)
[题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...
- 清华集训2015 V
#164. [清华集训2015]V http://uoj.ac/problem/164 统计 描述 提交 自定义测试 Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...
- BZOJ 4732 UOJ #268 [清华集训2016]数据交互 (树链剖分、线段树)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...
- 2018.07.28 uoj#169. 【UR #11】元旦老人与数列(线段树)
传送门 线段树好题. 维护区间加,区间取最大值,维护区间最小值,历史区间最小值. 同样先考虑不用维护历史区间最小值的情况,这个可以参考这道题的解法,维护区间最小和次小值可以解决前两个操作,然后使用历史 ...
- 2018.07.27 bzoj3064: Tyvj 1518 CPU监控(线段树)
传送门 线段树好题. 维护区间加,区间覆盖,区间最大,区间历史最大. 这个东西在国家集训队2016论文集之<区间最值操作与历史最值问题--杭州学军中学 吉如一>中讲的已经很详细了. 简单来 ...
- 2018.07.27 bzoj4695: 最假女选手(线段树)
传送门 线段树好题 支持区间加,区间取min" role="presentation" style="position: relative;"> ...
- 「清华集训2015」V
「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...
随机推荐
- 使用MATPLOTLIB 制图(小图)
import numpy as np import pandas as pd import matplotlib.pyplot as plt data = pd.read_csv('D:\\myfil ...
- Spring @Trasactionl 失效, JDK,CGLIB动态代理
@Transaction: http://blog.csdn.net/bao19901210/article/details/41724355 Spring上下文: http://blog.csd ...
- Error 2503 and 2502 when installing/uninstalling on Windows 10
1. Hold Ctrl+Shift and press Esc. 2. Locate “Windows Explorer” under “Windows processes”, now right ...
- [转]谈谈前端渲染 VS 后端渲染
首先,预编译跟前后端没有关系,预编译一样可以用于后端渲染. 看看下面的测试时间,单位: ms 模板字符串: var s = '{{#datas}}{{name}} abcdefg {{type}} { ...
- Java Magic. Part 4: sun.misc.Unsafe
Java Magic. Part 4: sun.misc.Unsafe @(Base)[JDK, Unsafe, magic, 黑魔法] 转载请写明:原文地址 系列文章: -Java Magic. P ...
- 常用类一一时间处理相关类一一java.util.Tomezone(java.util.Calendar , java.util.Date , java.text.DateFormat)
时间处理相关类 时间是一个一维的东东.所以,我们需要一把刻度尺来区表达和度量时间.在计算机世界,我们把1970 年 1 月 1 日 00:00:00定为基准时间,每个度量单位是毫秒(1秒的千分之一). ...
- 2基本类型数组和枚举类型——重拾Java
2.1 标识符和关键字 2.1.1标识符 标识符:用来标志类名.变量名.方法名.类型名.数组名.文件名的有效字符序列称为标识符.简单地说,标识符就是一个名字. Java关于标识符的语法规则 标识符由字 ...
- dom node 查找父级parentNode
var o = document.querySelectorAll("a[href='baidu.com']"); var p = o[o.length-1];console.lo ...
- 关于HSTS安全协议的全面详细解析
HTTP 严格传输安全(HSTS)是一种安全功能,web 服务器通过它来告诉浏览器仅用 HTTPS 来与之通讯,而不是使用 HTTP.HSTS是网站从HTTP到HTTPS中网站性能及安全优化非常重要的 ...
- WebDriverException: Message: f.QueryInterface is not a function
WebDriverException: Message: f.QueryInterface is not a function 使用webdriver打开c.highpin.cn,结果报错,见下图: ...