题目链接

UOJ #164

题解

首先,这道题有三种询问:区间加、区间减(减完对\(0\)取\(\max\))、区间修改。

可以用一种标记来表示——标记\((a, b)\)表示把原来的值加上\(a\)后对\(b\)取\(\max\)。

那么区间加\(x\)就是\((x, -\infty)\),区间减\(x\)就是\((-x, 0)\), 区间修改就是\((-\infty, x)\)。

然后,这道题有两个询问,一个询问当前值,一个询问历史最大值,于是我们打两种不同的标记,分别维护两个询问的答案:\((a_0, b_0)\)表示当前,\((a_1, b_1)\)表示历史最大值。

下面的问题就是如何下放标记(默认\((a, b)\)是原有的,\((c, d)\)是后来加上的)。

合并\((a_0, b_0)\)和\((c_0, d_0)\):\((a_0 + c_0, \max(b_0 + c_0, d_0))\)

合并\((a_1, b_1)\)和\((c_1, d_1)\):\((\max(a_1, a_0 + c_1), \max(b_1, b_0 + c_1, d_1))\)

然后就可以写了 = =

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
#define space putchar(' ')
#define enter putchar('\n')
typedef long long ll;
using namespace std;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int N = 500005;
const ll INF = 1e18;
int n, m;
ll a[4*N][2], b[4*N][2], val[N]; void upt(int k){
a[k][1] = max(a[k][1], a[k][0] + a[k >> 1][1]);
b[k][1] = max(b[k][1], max(b[k][0] + a[k >> 1][1], b[k >> 1][1]));
a[k][0] = max(a[k][0] + a[k >> 1][0], -INF);
b[k][0] = max(b[k][0] + a[k >> 1][0], b[k >> 1][0]);
}
void pushdown(int k){
upt(k << 1), upt(k << 1 | 1);
a[k][0] = a[k][1] = 0, b[k][0] = b[k][1] = -INF;
}
void change(int k, int l, int r, int ql, int qr, ll x, ll y){
if(ql <= l && qr >= r){
a[k][1] = max(a[k][1], (a[k][0] + x));
b[k][1] = max(b[k][1], max(b[k][0] + x, y));
a[k][0] = max(a[k][0] + x, -INF);
b[k][0] = max(b[k][0] + x, y);
return;
}
pushdown(k);
int mid = (l + r) >> 1;
if(ql <= mid) change(k << 1, l, mid, ql, qr, x, y);
if(qr > mid) change(k << 1 | 1, mid + 1, r, ql, qr, x, y);
}
ll query(int k, int l, int r, int p, int o){
if(l == r) return max(val[l] + a[k][o], b[k][o]);
pushdown(k);
int mid = (l + r) >> 1;
if(p <= mid) return query(k << 1, l, mid, p, o);
else return query(k << 1 | 1, mid + 1, r, p, o);
} int main(){ read(n), read(m);
for(int i = 1; i <= n; i++) read(val[i]);
int op, l, r;
ll x;
while(m--){
read(op);
if(op <= 3){
read(l), read(r), read(x);
if(op == 1) change(1, 1, n, l, r, x, -INF);
if(op == 2) change(1, 1, n, l, r, -x, 0);
if(op == 3) change(1, 1, n, l, r, -INF, x);
}
else read(x), write(query(1, 1, n, x, op - 4)), enter;
} return 0;
}

UOJ #164. 【清华集训2015】V | 线段树的更多相关文章

  1. UOJ #164 [清华集训2015]V (线段树)

    题目链接 http://uoj.ac/problem/164 题解 神仙线段树题. 首先赋值操作可以等价于减掉正无穷再加上\(x\). 假设某个位置从前到后的操作序列是: \(x_1,x_2,..., ...

  2. 【uoj#164】[清华集训2015]V 线段树维护历史最值

    题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...

  3. 【题解】P4247 [清华集训]序列操作(线段树修改DP)

    [题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...

  4. 清华集训2015 V

    #164. [清华集训2015]V http://uoj.ac/problem/164 统计 描述 提交 自定义测试 Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...

  5. BZOJ 4732 UOJ #268 [清华集训2016]数据交互 (树链剖分、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...

  6. 「清华集训2015」V

    「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...

  7. [UOJ#274][清华集训2016]温暖会指引我们前行

    [UOJ#274][清华集训2016]温暖会指引我们前行 试题描述 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一 ...

  8. 2018.07.28 uoj#164. 【清华集训2015】V(线段树)

    传送门 线段树好题. 要求支持的操作: 1.区间变成max(xi−a,0)" role="presentation" style="position: rela ...

  9. @uoj - 164@ 【清华集训2015】V

    目录 @description@ @solution@ @accepted code@ @details@ @description@ Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化 ...

随机推荐

  1. ThinkPad T43续命记

    // Description: 原作于2016年8月25日. Mr. Robot 最近有部叫<黑客军团>(Mr. Robot)的戏比较火.目前第二季已经出到一大半了,深得技术宅和技术宅仰慕 ...

  2. WPF CheckBox 滑块 样式 开关

    原文:WPF CheckBox 滑块 样式 开关 效果图 样式代码 <Style x:Key="CheckRadioFocusVisual"> <Setter P ...

  3. Codeforces 996E Leaving the Bar (随机化)

    题目连接:Leaving the Bar 题意:给你n个向量,你可以加这个向量或减这个向量,使得这些向量之和的长度小于1.5e6. 题解: 按照正常的贪心方法,最后的结果有可能大于1.5e6 .这里我 ...

  4. eclipse取消自动输入提示

    在设置Eclipse自动提示后,按a-z都会显示提示,但是我们需要键入Enter才会输入,而默认的所有都键入,非常弱智,可采用下面方法设置. 1,先找到相关的插件: window -> show ...

  5. ubuntu在指定的文件夹下创建python3和python2的虚拟环境

    1.用pip安装virtualenv sudo apt-get install python-virtualenv 2.创建python2和python3虚拟环境 2.1 创建python2的虚拟环境 ...

  6. centos6.8下LNMP (nginx1.8.0+php5.6.10+mysql5.6.12) - 部署手册

    在平时运维工作中,经常需要用到LNMP应用框架.以下对LNMP环境部署记录下: 1)前期准备:为了安装顺利,建议先使用yum安装依赖库[root@opd ~]#yum install -y make ...

  7. kvm虚拟化管理平台WebVirtMgr部署-完整记录(2)

    继上一篇kvm虚拟化管理平台WebVirtMgr部署-完整记录(1),接下来说说WebVirtMgr的日常配置:添加宿主机,创建虚机,磁盘扩容,快照等具体操作记录如下: 一.配置宿主机1.登录WebV ...

  8. Redis常用操作-------Set(集合)

    1.SADD key member [member ...] 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略. 假如 key 不存在,则创建一个 ...

  9. Freemaker的了解

    freemarket 模板技术 与web容器没什么关系 可以用struct2作为视图组件   第一步导入jar包 项目目录下建立一个templates目录 在此目录下建立一个模板文件a.ftl文件   ...

  10. PHP预防跨站脚本(XSS)攻击且不影响html代码显示效果

    什么是XSS 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意攻击者往 ...