【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博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...
随机推荐
- java随机数的生成
我们经常会用到随机数的生成,作为唯一性的id或者标识: long now = System.currentTimeMillis(); SimpleDateFormat dateFormat=new S ...
- virsh常用维护命令
virsh常用命令 一些常用命令参数 [root@kvm-server ~]# virsh --help #查看命令帮忙 [ro ...
- DB知识点记录
DB知识点记录 分页 SqlServer:ROW_NUMBER () over (ORDER BY ID) AS RN, MySql:limit Oracle:ROWNUM AS RN 数据表的基本结 ...
- Python中abs()和math.fabs()区别
描述:Python中fabs(x)方法返回x的绝对值.虽然类似于abs()函数,但是两个函数之间存在以下差异: abs()是一个内置函数,而fabs()在math模块中定义的. fabs()函数只适用 ...
- Windows10 Oracle ODBC安装配置
项目紧迫,需在短时间内交付成果,新团队成员,吐嘈之前数据库设计太low,很难看懂数据库表结构间的关系,为了使新同事更好的了解数据库表结构,特意使用powerDesigner对oracle.mysql数 ...
- PHP自定义生成二维码跳转地址
比较简单的一款PHP自定义生成二维码跳转地址,手机端微信扫码,自动跳转到定义好的链接.支持自定义生成二维码尺寸.间距等. 鼠标悬浮显示二维码弹出层,离开后消失.js实现,代码如下: $(fu ...
- VMware VSAN 入门与配置(一)
----VMware VSAN beta版已经出来一段时间了,今天终于正式发布(同时VMware View 5.3.1也正是发布,在5.3的基础上增加了VSAN的支持) VSAN 产品主页 http: ...
- python3【基础】-and和or的短路逻辑
1. 表达式只有一个逻辑运算符 python中哪些对象会被当成False,哪些又是True呢? 基本数据类型中的None.任何数值类型中的0.空字符串"",空列表[],空元组()和 ...
- BZOJ 1559 JSOI2009 密码 状压dp+AC自动机+搜索
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1559 分析: 这个题意真的是很**啊!!!直接说每一个字符串至少出现一次不就好了吗... ...
- Farm Irrigation ZOJ 2412(DFS连通图)
Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot ...