题目链接

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. C#批量插入数据到Sqlserver中的四种方式 - 转

    先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生成一个GUID算法所花的时间肯定比你从数据表中重新查询上一条记 ...

  2. Create-React-App 使用记录

    如果要修改 host 和 端口,需要在项目根目录添加 .env 文件,然后再文件中添加 HOST=dev.zhengtongauto.com PORT=3000 如果需要加上反向代理,需要处理接口跨域 ...

  3. HDU 1109 Run Away

    题目大意:给一个矩阵的长宽,再给n个点,求矩阵区域内某个点到各个点的最小距离的最大值,输出所求点的坐标 这道题我还是写了随机化乱搞,不过由于比较懒于是就没有写模拟退火,不过也是可以AC的 我们先初始随 ...

  4. Luogu P1896 [SCOI2005]互不侵犯

    一道超级简单的状压DP题所以说状压是个好东西 看数据范围,同时我们发现一个格子要么放国王or不放,因此可以用二进制数来表示某一行的国王放置信息 于是我们马上想到用\(f_{i,j}\)表示放了前\(i ...

  5. Spring Cloud 入门教程(九): 路由网关zuul

    在微服务架构中,需要几个关键的组件,服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个组件可以组建一个简单的微服务架构.客户端的请求首先经过负载均衡(zuul.Ngnix),再 ...

  6. vue 路由拦截、axios请求拦截

    路由拦截 项目中,有些页面需要登录后才能进入,例如,在某页面A,用户在操作前需要先进入登录页(此时需要将上一页的地址(/survey/start)作为query存入login页面的地址中,如: htt ...

  7. 【JVM.3】虚拟机性能监控与故障处理工具

    一.概述 经过前面两章对于虚拟机内存分配与回收技术各方面的介绍,相信读者已经建立了一套比较完整的理论基础.理论总是作为指导实践的工具,能把这些执行应用到实际工作中才是我们的最终目的.接下来我们会从实践 ...

  8. C#_反射机制

    一:反射的定义 审查元数据并收集关于它的类型信息的能力.元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等. Sys ...

  9. Hybrid APP基础篇(一)->什么是Hybrid App

    最新更新 一个开源的快速混合开发框架:https://github.com/quickhybrid/quickhybrid Android.iOS.JS三端内容初步都已经完成,有完善的设计思路.教程以 ...

  10. 生产者消费者模式 php 【转】

    在工作中常常听到某某大牛之间的交谈会涉及到,xx消费者啊啥的,到底什么大牛之间讲的是什么? 这篇文章主要解决三个问题: 1.到底什么是生产者和消费者,以及它们之间的故事 2.它们之间靠什么交流 3.应 ...