题目链接

\(Description\)

有一个长为n的序列Ai,要求支持查询[l,r]的最值、历史最值,区间加/重设

\(Solution\)

线段树,每个点再维护一个历史(从0到现在)最大值、历史(从上次下传标记到现在)最大的set,add标记

PushDown时肯定是先下放历史标记,之后再用当前标记更新

  1. /*
  2. 要记得当要PushDown某个点时,last,now的val都是历史的(下传前),
  3. 所以now.v + last.add就是下传前值+[下传前到现在]一次最大的修改的值
  4. 不能只在Set后清空add。像代码这么做很正确,可以稍微画个图
  5. 每次now的操作不仅要更新now,还要更新last
  6. */
  7. #include<cstdio>
  8. #include<cctype>
  9. #include<algorithm>
  10. #define gc() getchar()
  11. #define lson node[node[rt].ls]
  12. #define rson node[node[rt].rs]
  13. const int N=1e5+5,INF=0x3f3f3f3f;
  14. int n,m;
  15. inline int read()
  16. {
  17. int now=0,f=1;register char c=gc();
  18. for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
  19. for(;isdigit(c);now=now*10+c-'0',c=gc());
  20. return now*f;
  21. }
  22. #define now node[rt]
  23. struct Seg_Tree
  24. {
  25. int tot;
  26. struct Node
  27. {
  28. int ls,rs,nv,lv,nadd,ladd,nset,lset;
  29. }node[N<<1];
  30. inline void PushUp(int rt)
  31. {
  32. now.nv = std::max(lson.nv, rson.nv);
  33. now.lv = std::max(lson.lv, rson.lv);
  34. }
  35. void Build(int l,int r)
  36. {
  37. int rt=tot++;
  38. now.nadd=now.ladd=0, now.nset=now.lset=-INF;
  39. if(l==r) now.nv=now.lv=read();
  40. else
  41. {
  42. int m=l+r>>1;
  43. now.ls=tot, Build(l,m);
  44. now.rs=tot, Build(m+1,r);
  45. PushUp(rt);
  46. }
  47. }
  48. inline void Update(int &x,int y) {x = std::max(x,y);}
  49. inline void L_Set(int rt,int v)
  50. {
  51. Update(now.lv, v);
  52. Update(now.lset, v);
  53. }
  54. inline void L_Add(int rt,int v)
  55. {
  56. Update(now.lv, now.nv+v);
  57. if(now.nset>-INF) Update(now.lset, now.nset+v);//判断的是nset>-INF(用now更新last关last什么事)//necessary!
  58. else Update(now.ladd, now.nadd+v);
  59. //如果之后rt.ladd下传了,那就没了;如果没下传,仍是rt下传前情况(历史)
  60. //即可以用now.ladd;或是用上次下传前标记+到现在修改最大值
  61. }
  62. inline void N_Set(int rt,int v)
  63. {
  64. Update(now.lv, now.nv=v);
  65. Update(now.lset, now.nset=v);
  66. now.nadd = 0;
  67. }
  68. inline void N_Add(int rt,int v)
  69. {
  70. Update(now.lv, now.nv+=v);
  71. if(now.nset>-INF) Update(now.lset, now.nset+=v);
  72. //Update的是lset,not ladd,现在更新的是set不是add//在被set影响后,所有操作都可看做set
  73. else Update(now.ladd, now.nadd+=v);
  74. }
  75. void PushDown(int rt)
  76. {
  77. if(now.ladd)
  78. L_Add(now.ls,now.ladd),L_Add(now.rs,now.ladd),now.ladd=0;
  79. if(now.lset>-INF)
  80. L_Set(now.ls,now.lset),L_Set(now.rs,now.lset),now.lset=-INF;
  81. if(now.nadd)
  82. N_Add(now.ls,now.nadd),N_Add(now.rs,now.nadd),now.nadd=0;
  83. if(now.nset>-INF)
  84. N_Set(now.ls,now.nset),N_Set(now.rs,now.nset),now.nset=-INF;
  85. }
  86. void Modify_Add(int l,int r,int rt,int L,int R,int v)
  87. {
  88. if(L<=l && r<=R) {N_Add(rt,v); return;}
  89. PushDown(rt);
  90. int m=l+r>>1;
  91. if(L<=m) Modify_Add(l,m,now.ls,L,R,v);
  92. if(m<R) Modify_Add(m+1,r,now.rs,L,R,v);
  93. PushUp(rt);
  94. }
  95. void Modify_Set(int l,int r,int rt,int L,int R,int v)
  96. {
  97. if(L<=l && r<=R) {N_Set(rt,v); return;}
  98. PushDown(rt);
  99. int m=l+r>>1;
  100. if(L<=m) Modify_Set(l,m,now.ls,L,R,v);
  101. if(m<R) Modify_Set(m+1,r,now.rs,L,R,v);
  102. PushUp(rt);
  103. }
  104. int Query(int l,int r,int rt,int L,int R,bool opt)
  105. {
  106. if(L<=l && r<=R) return opt?now.nv:now.lv;
  107. PushDown(rt);
  108. int m=l+r>>1;
  109. if(L<=m)
  110. if(m<R) return std::max(Query(l,m,now.ls,L,R,opt),Query(m+1,r,now.rs,L,R,opt));
  111. else return Query(l,m,now.ls,L,R,opt);
  112. return Query(m+1,r,now.rs,L,R,opt);
  113. }
  114. }t;
  115. #undef now
  116. int main()
  117. {
  118. n=read(), t.Build(1,n), m=read();
  119. char opt[3]; int x,y,z;
  120. while(m--)
  121. {
  122. scanf("%s",opt), x=read(),y=read();
  123. switch(opt[0])
  124. {
  125. case 'Q': printf("%d\n",t.Query(1,n,0,x,y,1)); break;
  126. case 'A': printf("%d\n",t.Query(1,n,0,x,y,0)); break;
  127. case 'P': z=read(), t.Modify_Add(1,n,0,x,y,z); break;
  128. case 'C': z=read(), t.Modify_Set(1,n,0,x,y,z); break;
  129. }
  130. }
  131. return 0;
  132. }

BZOJ.3064.CPU监控(线段树 历史最值)的更多相关文章

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

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

  2. BZOJ 3064 CPU监控

    题目链接:CPU监控 学习一番线段树的历史标记- 这道题就是区间加法,区间赋值,要询问区间最大值 和 区间历史最大值的最大值. 然后这种题就是在现有标记的基础上多弄一套标记,维护这个点出现过的最大的标 ...

  3. CPU监控 线段树裸题

    LINK:bzoj3064 此题甚好码了20min停下来思考的时候才发现不对的地方有点坑... 还真不好写来着 可这的确是线段树的裸题...我觉得我写应该没有什么大问题 不过思路非常的紊乱 如果是自己 ...

  4. BZOJ3064 Tyvj 1518 CPU监控 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3064 题意概括 一个序列,要你支持以下操作: 1. 区间询问最大值 2. 区间询问历史最大值 3. ...

  5. Bzoj 2752 高速公路 (期望,线段树)

    Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...

  6. MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值

    F - Permutation 思路:对于当前的值x, 只需要知道x + k, x - k这两个值是否出现在其左右两侧,又因为每个值只有一个, 所以可以转换成,x+k, x-k在到x所在位置的时候是否 ...

  7. 【bzoj4695】最假女选手 线段树区间最值操作

    题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作:1.给一个区间[L,R] 加上一个数x 2.把一个区间[L,R] 里小于x 的数变成x 3.把一个区间[L,R] 里大于 ...

  8. 【bzoj4355】Play with sequence 线段树区间最值操作

    题目描述 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a[V]都赋值为C. 2)给出参数U,V,C,对于区间[U,V]里的每个数 ...

  9. 【hdu5306】Gorgeous Sequence 线段树区间最值操作

    题目描述 给你一个序列,支持三种操作: $0\ x\ y\ t$ :将 $[x,y]$ 内大于 $t$ 的数变为 $t$ :$1\ x\ y$ :求 $[x,y]$ 内所有数的最大值:$2\ x\ y ...

随机推荐

  1. UML和模式应用4:初始阶段(7)--其它需求

    1.前言 本文主要讲述除用例的其它需求制品. 2.TODO

  2. Linux电源管理【转】

    转自:http://www.cnblogs.com/sky-zhang/archive/2012/06/05/2536807.html PM notifier机制: 应用场景: There are s ...

  3. CentOS6.5运行yum报错:No module named yum

    公司测试机环境不知道给我卸了什么包,导致yum运行报错状况: 报错情况: There was a problem importing one of the Python modulesrequired ...

  4. centos中创建自动备份Mysql脚本任务并定期删除过期备份

    背景: OA系统数据库是mysql,引擎为myisam,可以直接通过拷贝数据库文件的方式进行备份 创建只备份数据库的任务: 创建保存mysql数据库备份文件的目录mysqlbak mkdir /hom ...

  5. Android主题切换

    一.APK文件方式:(CM9方案) 我们知道Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户的(Android 系统是基于Linux) ...

  6. centos7 Firewalld操作集合

    =============================================== 2019/4/15_第1次修改                       ccb_warlock == ...

  7. fastjson序列化排序问题

    fastjson序列化,默认是用字母排序, 那么怎么来实现按照自己定义的顺序输出,想要的json串呢? 直接上代码: import com.alibaba.fastjson.annotation.JS ...

  8. python魔法函数(二)之__getitem__、__len__、__iter__

    魔法函数会增强python类的类型,独立存在 __getitem class Company: def __init__(self, employees): self.employees = empl ...

  9. 【ES】代码例子

    #!/usr/bin/env python #coding=utf-8 from elasticsearch import Elasticsearch from elasticsearch_dsl i ...

  10. 使用mybatis-spring-boot-starter如何打印sql语句

    只需要将接口文件的日志设置为debug即可. 例如你的mapper接口所在的文件夹是 com.demo.mapper 那么在application.properties配置文件中添加 logging. ...