【uoj#164】[清华集训2015]V 线段树维护历史最值
给你一个长度为 $n$ 的序列,支持五种操作:
$1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ ;
$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并与 $0$ 取 $\text{max}$ ;
$3\ l\ r\ x$ :将 $[l,r]$ 内的数变为 $x$ ;
$4\ y$ :询问第 $y$ 个数的值;
$5\ y$ :询问第 $y$ 个数的历史最大值。
$n,m\le 5\times 10^5,0\le x\le 10^9$
题解
线段树维护历史最值
线段树维护历史最值的方法可以参考 CPU监控 (那道题我是用这道题的方法做的。。。)
那么按照同样的方法,操作1可以看作打标记 $(x,0)$ ,操作2可以看作打标记 $(-x,0)$ ,操作3可以看作打标记 $(-\infty ,x)$ 。
用同样的方法进行标记的维护即可。
由于本题是单点查询,因此可以只考虑标记对原值的影响,不需要维护区间最值及区间历史最值。
时间复杂度 $O(m\log n)$
#include <cstdio>
#include <algorithm>
#define N 500010
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
typedef long long ll;
const ll inf = 1ll << 60;
struct data
{
ll x , y;
data(ll a = 0 , ll b = -inf) {x = a , y = b;}
data operator+(const data &a)const {return data(max(x + a.x , -inf) , max(y + a.x , a.y));}
data operator*(const data &a)const {return data(max(x , a.x) , max(y , a.y));}
}ntag[N << 2] , ptag[N << 2];
ll a[N];
inline void pushdown(int x)
{
int l = x << 1 , r = x << 1 | 1;
ptag[l] = ptag[l] * (ntag[l] + ptag[x]);
ntag[l] = ntag[l] + ntag[x];
ptag[r] = ptag[r] * (ntag[r] + ptag[x]);
ntag[r] = ntag[r] + ntag[x];
ptag[x] = ntag[x] = data();
}
void build(int l , int r , int x)
{
ntag[x] = ptag[x] = data();
if(l == r)
{
scanf("%lld" , &a[l]);
return;
}
int mid = (l + r) >> 1;
build(lson) , build(rson);
}
void update(int b , int e , data v , int l , int r , int x)
{
if(b <= l && r <= e)
{
ptag[x] = ptag[x] * (ntag[x] + v);
ntag[x] = ntag[x] + v;
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if(b <= mid) update(b , e , v , lson);
if(e > mid) update(b , e , v , rson);
}
ll query(int p , bool flag , int l , int r , int x)
{
if(l == r)
{
if(flag) return max(a[p] + ptag[x].x , ptag[x].y);
else return max(a[p] + ntag[x].x , ntag[x].y);
}
pushdown(x);
int mid = (l + r) >> 1;
if(p <= mid) return query(p , flag , lson);
else return query(p , flag , rson);
}
int main()
{
int n , m , opt , x , y;
ll z;
scanf("%d%d" , &n , &m);
build(1 , n , 1);
while(m -- )
{
scanf("%d%d" , &opt , &x);
if(opt == 1) scanf("%d%lld" , &y , &z) , update(x , y , data(z , 0) , 1 , n , 1);
if(opt == 2) scanf("%d%lld" , &y , &z) , update(x , y , data(-z , 0) , 1 , n , 1);
if(opt == 3) scanf("%d%lld" , &y , &z) , update(x , y , data(-inf , z) , 1 , n , 1);
if(opt == 4) printf("%lld\n" , query(x , 0 , 1 , n , 1));
if(opt == 5) printf("%lld\n" , query(x , 1 , 1 , n , 1));
}
return 0;
}
【uoj#164】[清华集训2015]V 线段树维护历史最值的更多相关文章
- UOJ #164 [清华集训2015]V (线段树)
题目链接 http://uoj.ac/problem/164 题解 神仙线段树题. 首先赋值操作可以等价于减掉正无穷再加上\(x\). 假设某个位置从前到后的操作序列是: \(x_1,x_2,..., ...
- LOJ 164 【清华集训2015】V——线段树维护历史最值
题目:http://uoj.ac/problem/164 把操作改成形如 ( a,b ) 表示加上 a 之后对 b 取 max 的意思. 每个点维护当前的 a , b ,还有历史最大的 a , b 即 ...
- 【bzoj3064】Tyvj 1518 CPU监控 线段树维护历史最值
题目描述 给你一个序列,支持4种操作:1.查询区间最大值:2.查询区间历史最大值:3.区间加:4.区间赋值. 输入 第一行一个正整数T,表示Bob需要监视CPU的总时间. 然后第二行给出T个数表示在你 ...
- SPOJ 1557 GSS2 - Can you answer these queries II (线段树+维护历史最值)
都说这题是 GSS 系列中最难的,今天做了一下,名副其实 首先你可以想到各种各样的在线乱搞想法,线段树,主席树,平衡树,等等,但发现都不太可行. 注意到题目也没有说强制在线,因此可以想到离线地去解决这 ...
- 【题解】P4247 [清华集训]序列操作(线段树修改DP)
[题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...
- 滑动窗口(poj,线段树维护区间最值)
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- CF213E Two Permutations 线段树维护哈希值
当初竟然看成子串了$qwq$,不过老师的$ppt$也错了$qwq$ 由于子序列一定是的排列,所以考虑插入$1$到$m$到$n-m+1$到$n$; 如何判断呢?可以用哈希$qwq$: 我们用线段树维护哈 ...
- BZOJ 4732 UOJ #268 [清华集训2016]数据交互 (树链剖分、线段树)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...
- 清华集训2015 V
#164. [清华集训2015]V http://uoj.ac/problem/164 统计 描述 提交 自定义测试 Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...
随机推荐
- 【LG4317】花神的数论题
[LG4317]花神的数论题 题面 洛谷 题解 设\(f_{i,up,tmp,d}\)表示当前在第\(i\)位,是否卡上界,有\(tmp\)个一,目标是几个一的方案数 最后将所有\(d\)固定,套数位 ...
- Elasticsearch5.x版本中对Text类型进行聚合时提示illegal_argument_exception
Having this field in my mapping "answer": { "type": "text", "fiel ...
- 获取Java线程返回值的几种方式
在实际开发过程中,我们有时候会遇到主线程调用子线程,要等待子线程返回的结果来进行下一步动作的业务. 那么怎么获取子线程返回的值呢,我这里总结了三种方式: 主线程等待. Join方法等待. 实现Call ...
- Oracle创建表管理表
--创建图书表 create table books_lib ( book_id ) primary key, --unique¬ null book_name ) not null ) ...
- [python] Queue.Queue vs. collections.deque
https://stackoverflow.com/questions/717148/queue-queue-vs-collections-deque/717199#717199 Queue,Queu ...
- PowerDesigne 建立概念数据模型
本文主要介绍PowerDesigner概念数据模型以及实体.属性创建. 一.新建概念数据模型1)选择File-->New,弹出如图所示对话框,选择CDM模型(即概念数据模型)建立模型. 2)完成 ...
- 常用 php server
php编程中经常需要用到一些服务器的一些资料,我把常用的用高亮的方式贴出来,其余的放在后面.方便以后查阅 复制代码代码如下: $_SERVER['HTTP_ACCEPT_LANGUAGE']/ ...
- 希尔排序(java实现)
上篇blog中介绍的直接插入排序,希尔排序就是对直接插入排序的一个优化.比如有这么一种情况:对一个无序数组进行从小到大的排序,但是数组的最后一个位置的数是最小的,我们要把它挪到第一个位置,其他位置的都 ...
- FivePlus——团队展示
光耀101 <光耀101>是福州大学数计学院计算机专业推出的中国首部程序猿脱发养成节目.由张栋担任发起人,刘晨瑶.畅畅担任导师. 该节目召集了你猜多少位选手,通过任务.训练.考核,让选 ...
- 团队Alpha冲刺(一)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...