题目描述

给你一个长度为 $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)$

  1. #include <cstdio>
  2. #include <algorithm>
  3. #define N 500010
  4. #define lson l , mid , x << 1
  5. #define rson mid + 1 , r , x << 1 | 1
  6. using namespace std;
  7. typedef long long ll;
  8. const ll inf = 1ll << 60;
  9. struct data
  10. {
  11. ll x , y;
  12. data(ll a = 0 , ll b = -inf) {x = a , y = b;}
  13. data operator+(const data &a)const {return data(max(x + a.x , -inf) , max(y + a.x , a.y));}
  14. data operator*(const data &a)const {return data(max(x , a.x) , max(y , a.y));}
  15. }ntag[N << 2] , ptag[N << 2];
  16. ll a[N];
  17. inline void pushdown(int x)
  18. {
  19. int l = x << 1 , r = x << 1 | 1;
  20. ptag[l] = ptag[l] * (ntag[l] + ptag[x]);
  21. ntag[l] = ntag[l] + ntag[x];
  22. ptag[r] = ptag[r] * (ntag[r] + ptag[x]);
  23. ntag[r] = ntag[r] + ntag[x];
  24. ptag[x] = ntag[x] = data();
  25. }
  26. void build(int l , int r , int x)
  27. {
  28. ntag[x] = ptag[x] = data();
  29. if(l == r)
  30. {
  31. scanf("%lld" , &a[l]);
  32. return;
  33. }
  34. int mid = (l + r) >> 1;
  35. build(lson) , build(rson);
  36. }
  37. void update(int b , int e , data v , int l , int r , int x)
  38. {
  39. if(b <= l && r <= e)
  40. {
  41. ptag[x] = ptag[x] * (ntag[x] + v);
  42. ntag[x] = ntag[x] + v;
  43. return;
  44. }
  45. pushdown(x);
  46. int mid = (l + r) >> 1;
  47. if(b <= mid) update(b , e , v , lson);
  48. if(e > mid) update(b , e , v , rson);
  49. }
  50. ll query(int p , bool flag , int l , int r , int x)
  51. {
  52. if(l == r)
  53. {
  54. if(flag) return max(a[p] + ptag[x].x , ptag[x].y);
  55. else return max(a[p] + ntag[x].x , ntag[x].y);
  56. }
  57. pushdown(x);
  58. int mid = (l + r) >> 1;
  59. if(p <= mid) return query(p , flag , lson);
  60. else return query(p , flag , rson);
  61. }
  62. int main()
  63. {
  64. int n , m , opt , x , y;
  65. ll z;
  66. scanf("%d%d" , &n , &m);
  67. build(1 , n , 1);
  68. while(m -- )
  69. {
  70. scanf("%d%d" , &opt , &x);
  71. if(opt == 1) scanf("%d%lld" , &y , &z) , update(x , y , data(z , 0) , 1 , n , 1);
  72. if(opt == 2) scanf("%d%lld" , &y , &z) , update(x , y , data(-z , 0) , 1 , n , 1);
  73. if(opt == 3) scanf("%d%lld" , &y , &z) , update(x , y , data(-inf , z) , 1 , n , 1);
  74. if(opt == 4) printf("%lld\n" , query(x , 0 , 1 , n , 1));
  75. if(opt == 5) printf("%lld\n" , query(x , 1 , 1 , n , 1));
  76. }
  77. return 0;
  78. }

【uoj#164】[清华集训2015]V 线段树维护历史最值的更多相关文章

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

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

  2. LOJ 164 【清华集训2015】V——线段树维护历史最值

    题目:http://uoj.ac/problem/164 把操作改成形如 ( a,b ) 表示加上 a 之后对 b 取 max 的意思. 每个点维护当前的 a , b ,还有历史最大的 a , b 即 ...

  3. 【bzoj3064】Tyvj 1518 CPU监控 线段树维护历史最值

    题目描述 给你一个序列,支持4种操作:1.查询区间最大值:2.查询区间历史最大值:3.区间加:4.区间赋值. 输入 第一行一个正整数T,表示Bob需要监视CPU的总时间. 然后第二行给出T个数表示在你 ...

  4. SPOJ 1557 GSS2 - Can you answer these queries II (线段树+维护历史最值)

    都说这题是 GSS 系列中最难的,今天做了一下,名副其实 首先你可以想到各种各样的在线乱搞想法,线段树,主席树,平衡树,等等,但发现都不太可行. 注意到题目也没有说强制在线,因此可以想到离线地去解决这 ...

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

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

  6. 滑动窗口(poj,线段树维护区间最值)

    题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...

  7. CF213E Two Permutations 线段树维护哈希值

    当初竟然看成子串了$qwq$,不过老师的$ppt$也错了$qwq$ 由于子序列一定是的排列,所以考虑插入$1$到$m$到$n-m+1$到$n$; 如何判断呢?可以用哈希$qwq$: 我们用线段树维护哈 ...

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

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

  9. 清华集训2015 V

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

随机推荐

  1. java随机数的生成

    我们经常会用到随机数的生成,作为唯一性的id或者标识: long now = System.currentTimeMillis(); SimpleDateFormat dateFormat=new S ...

  2. virsh常用维护命令

    virsh常用命令 一些常用命令参数 [root@kvm-server ~]# virsh --help                                     #查看命令帮忙 [ro ...

  3. DB知识点记录

    DB知识点记录 分页 SqlServer:ROW_NUMBER () over (ORDER BY ID) AS RN, MySql:limit Oracle:ROWNUM AS RN 数据表的基本结 ...

  4. Python中abs()和math.fabs()区别

    描述:Python中fabs(x)方法返回x的绝对值.虽然类似于abs()函数,但是两个函数之间存在以下差异: abs()是一个内置函数,而fabs()在math模块中定义的. fabs()函数只适用 ...

  5. Windows10 Oracle ODBC安装配置

    项目紧迫,需在短时间内交付成果,新团队成员,吐嘈之前数据库设计太low,很难看懂数据库表结构间的关系,为了使新同事更好的了解数据库表结构,特意使用powerDesigner对oracle.mysql数 ...

  6. PHP自定义生成二维码跳转地址

      比较简单的一款PHP自定义生成二维码跳转地址,手机端微信扫码,自动跳转到定义好的链接.支持自定义生成二维码尺寸.间距等.    鼠标悬浮显示二维码弹出层,离开后消失.js实现,代码如下: $(fu ...

  7. VMware VSAN 入门与配置(一)

    ----VMware VSAN beta版已经出来一段时间了,今天终于正式发布(同时VMware View 5.3.1也正是发布,在5.3的基础上增加了VSAN的支持) VSAN 产品主页 http: ...

  8. python3【基础】-and和or的短路逻辑

    1. 表达式只有一个逻辑运算符 python中哪些对象会被当成False,哪些又是True呢? 基本数据类型中的None.任何数值类型中的0.空字符串"",空列表[],空元组()和 ...

  9. BZOJ 1559 JSOI2009 密码 状压dp+AC自动机+搜索

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1559 分析: 这个题意真的是很**啊!!!直接说每一个字符串至少出现一次不就好了吗... ...

  10. 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 ...