「清华集训2015」V

题目大意:

你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值。

解题思路

观察发现,每一种修改操作都可以用一个函数 \(f(x) = \max(x+a,b)\) 来表示。

操作 1: \(f(x) = (x,0)\)。

操作 2:\(f(x)=(-x, 0)\)。

操作 \(3\):\(f(x)=-(inf,0)\)。

这东西显然满足结合律,事实上还是封闭的

\[f1(f2(x)) = \max(\max(x+f2a,f2b)+f1a,f1b) \\
=\max(x+f2a+f1a,f2b+f1a,f1b) \\
=\max(x+f1a+f2a,\max(f1a+f2b,f1b))
\]

然后每一次操作把函数当做标记打在线段树对应节点上,直接合并标记就可以做单点查询了。注意这里合并有先后顺序,显然儿子的标记的时间一定早于父亲的标记,不然就被 \(\text{pushdown}\) 了,那么只要令儿子的标记为 \(f2\) ,父亲的标记为 \(f1\) 这样合并就好了。

考虑求历史最大值,本质上是要维护每一个节点从上一次下放到当前所有时刻标记的最大值,每次下放标记的时候维护儿子的答案即可。历史最大值也看成 \(\max(x+a,b)\) 的形式维护就好了。

\[f1(f2(x))=\max(x+\max(f1a,f1a),\max(f1b,f2b))
\]

####code

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf ((ll)(1e17))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
} #define pii pair<int, int>
#define int ll
#define fi first
#define se second const int N = 500005;
int a[N], n, m;
pii max(pii A, pii B){
return make_pair(max(A.fi, B.fi), max(A.se, B.se));
}
pii operator + (pii A, pii B){
pii C = make_pair(max(A.fi + B.fi, -inf), max(A.se + B.fi, B.se));
return C;
}
namespace Seg{
#define lson (u << 1)
#define rson (u << 1 | 1)
#define mid ((l + r) >> 1)
pii tag[N<<2], his[N<<2];
inline void pushdown(int u){
if(!tag[u].fi && !tag[u].se) return;
his[lson] = max(his[lson], tag[lson] + his[u]);
his[rson] = max(his[rson], tag[rson] + his[u]);
tag[lson] = tag[lson] + tag[u], tag[rson] = tag[rson] + tag[u];
tag[u] = make_pair(0ll, 0ll), his[u] = make_pair(0, 0);
}
inline void change(int u, int l, int r, int L, int R, pii x){
if(l >= L && r <= R){
tag[u] = tag[u] + x, his[u] = max(his[u], tag[u]);
return;
}
pushdown(u);
if(L <= mid) change(lson, l, mid, L, R, x);
if(mid < R) change(rson, mid + 1, r, L, R, x);
}
inline pii query(int u, int l, int r, int pos, int x){
if(l == r) return x ? his[u] : tag[u];
pushdown(u);
return pos <= mid ? query(lson, l, mid, pos, x) : query(rson, mid + 1, r, pos, x);
}
}
signed main(){
read(n), read(m);
for(int i = 1; i <= n; i++) read(a[i]);
for(int i = 1, op, l, r, x; i <= m; i++){
read(op);
if(op == 1){
read(l), read(r), read(x);
Seg::change(1, 1, n, l, r, make_pair(x, 0ll));
}
if(op == 2){
read(l), read(r), read(x);
Seg::change(1, 1, n, l, r, make_pair(-x, 0ll));
}
if(op == 3){
read(l), read(r), read(x);
Seg::change(1, 1, n, l, r, make_pair(-inf, x));
}
if(op >= 4){
read(x); pii now = Seg::query(1, 1, n, x, op == 5);
printf("%lld\n", max(a[x] + now.fi, now.se));
}
}
return 0;
}

「清华集训2015」V的更多相关文章

  1. 「题解」「UOJ-164」「清华集训2015」V

    目录 题目 原题目 简要题目 正解 这道题题目简洁新颖,吸引读者阅读兴趣... 题目 原题目 点这里 简要题目 需要你维护长度为n的序列并支持下列操作: 区间加法: 区间赋值: 区间每个 \(a_i\ ...

  2. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  3. Loj #2321. 「清华集训 2017」无限之环

    Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...

  4. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

  5. [LOJ#2326]「清华集训 2017」简单数据结构

    [LOJ#2326]「清华集训 2017」简单数据结构 试题描述 参加完IOI2018之后就是姚班面试.而你,由于讨厌物理.并且想成为乔布斯一样的创业家,被成功踢回贵系. 转眼,时间的指针被指向201 ...

  6. [LOJ#2323]「清华集训 2017」小Y和地铁

    [LOJ#2323]「清华集训 2017」小Y和地铁 试题描述 小Y是一个爱好旅行的OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的 ...

  7. Loj #2331. 「清华集训 2017」某位歌姬的故事

    Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...

  8. loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主

    #2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较   题目描述 "A fight? Co ...

  9. [LOJ#2330]「清华集训 2017」榕树之心

    [LOJ#2330]「清华集训 2017」榕树之心 试题描述 深秋.冷风吹散了最后一丝夏日的暑气,也吹落了榕树脚下灌木丛的叶子.相识数年的Evan和Lyra再次回到了小时候见面的茂盛榕树之下.小溪依旧 ...

随机推荐

  1. MyBatis数据库字段和实体对象属性名不一致的解决方案

    数据库和对象的属性名不一致是很常见的问题,这个时候依从表字段到对象属性名的按名称匹配映射已经搞不定这个了,下面是几种解决方案. 1. 开启驼峰转换 如果数据库中的字段名与对象只是简单的不一致的话,比如 ...

  2. JFinal向客户端渲染图片的方法

    JFinal提供了好几种方便的render但是不知道为啥就是没有提供直接渲染图片的render,如果我们直接在Controller的方法中往输入流中写的话是还是会有默认的render生效的,比如下面这 ...

  3. MSSQL 基础知识002

    ---启用sa账号 1. 先使用一个windows账号登陆. 2.在数据库实例上面右键,属性,安全性,登录名,sa. 右键,属性. 常规,修改sa的密码. 状态,启用sa账号. 主键的作用: 1.唯一 ...

  4. 日常开发技巧:x11-forward,使用远程机器的gui程序

    背景 日常用过ssh登录服务器进行工作,尽管大部分时间,都只需要终端操作,编辑源码也是vim就够用了. 但有时候,还是需要使用gui程序的,比如打开一份pdf,word,ppt,excel等. 碰到这 ...

  5. linux下C语言实现多线程通信—环形缓冲区,可用于生产者(producer)/消费者(consumer)【转】

    转自:http://blog.chinaunix.net/uid-28458801-id-4262445.html 操作系统:ubuntu10.04 前言:     在嵌入式开发中,只要是带操作系统的 ...

  6. 如何在Linux下用C/C++语言操作数据库sqlite3(很不错!设计编译链接等很多问题!)

    from : http://blog.chinaunix.NET/uid-21556133-id-118208.html 安装Sqlite3: 从www.sqlite.org上下载Sqlite3.2. ...

  7. Android 反编译神器jadx的使用

    一.前言 今天介绍一个非常好用的反编译的工具 jadx .jadx 的功能非常的强大,对我而言,基本上满足日常反编译需求. jadx 优点: 图形化的界面. 拖拽式的操作. 反编译输出 Java 代码 ...

  8. ubuntu遇到的 the system is runing low-graphics mode 问题

    不知道修改了什么,然后开机显示the system is runing low-graphics mode 看过博客使用如下方法成功进入系统,但是显示分辨率很低,显示 built-in display ...

  9. 垃圾回收算法与 JVM 垃圾回收器综述(转)

    垃圾回收算法与 JVM 垃圾回收器综述 我们常说的垃圾回收算法可以分为两部分:对象的查找算法与真正的回收方法.不同回收器的实现细节各有不同,但总的来说基本所有的回收器都会关注如下两个方面:找出所有的存 ...

  10. 3.rabbitmq 发布/订阅

    1. 发布者 #coding:utf8 import pika import json import sys message = ''.join(sys.argv[1:]) or "hell ...