题目描述

维护一个长度为N的序列a,现在有三种操作:
1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a[V]都赋值为C。
2)给出参数U,V,C,对于区间[U,V]里的每个数i,将a[i]赋值为max(a[i]+C,0)。
3)给出参数U,V,输出a[U],a[U+1],...,a[V-1],a[V]里值为0的数字个数。

输入

第一行包含两个正整数N,M(1<=N,M<=300000),分别表示序列长度和操作个数。
第二行包含N个整数,其中第i个数表示a[i](0<=a[i]<=10^9),描述序列的初始状态。
接下来M行描述M个操作,保证1<=U<=V<=N,对于操作1,0<=C<=10^9,对于操作2,|C|<=10^9。

输出

输出若干行,每行一个整数,依次回答每个操作3的问题。

样例输入

5 3
6 4 6 6 4
2 1 5 -5
1 3 4 4
3 1 5

样例输出

2


题解

线段树区间最值操作

考虑到操作1的 $C\le 0$ ,因此 $0$ 只可能出现在最小值。所以要统计 $0$ 的个数,只需要统计:最小值是不是0、最小值个数即可。

对于操作1直接区间赋值,操作2我们拆成两个操作:区间+C直接加,区间最大值操作参考 吉老师的Segment tree Beats! ,维护最小值、严格次小值即可。

注意标记下传顺序:区间赋值>区间加>区间最大操作。

同样,区间最大操作可以不维护标记,直接下传最小值。

时间复杂度 $O(n\log^2 n)$ (吉老师表示PPT里的证明是萎的...复杂度证明参考集训队论文)

  1. #include <cstdio>
  2. #include <algorithm>
  3. #define N 1200010
  4. #define inf 1ll << 62
  5. #define lson l , mid , x << 1
  6. #define rson mid + 1 , r , x << 1 | 1
  7. using namespace std;
  8. typedef long long ll;
  9. ll mn[N] , se[N] , cov[N] , add[N];
  10. int mc[N];
  11. inline void pushup(int x)
  12. {
  13. int ls = x << 1 , rs = x << 1 | 1;
  14. if(mn[ls] < mn[rs]) mn[x] = mn[ls] , mc[x] = mc[ls] , se[x] = min(se[ls] , mn[rs]);
  15. if(mn[ls] > mn[rs]) mn[x] = mn[rs] , mc[x] = mc[rs] , se[x] = min(mn[ls] , se[rs]);
  16. if(mn[ls] == mn[rs]) mn[x] = mn[ls] , mc[x] = mc[ls] + mc[rs] , se[x] = min(se[ls] , se[rs]);
  17. }
  18. inline void pushdown(int l , int r , int x)
  19. {
  20. int ls = x << 1 , rs = x << 1 | 1;
  21. if(~cov[x])
  22. {
  23. int mid = (l + r) >> 1;
  24. mn[ls] = cov[x] , mc[ls] = mid - l + 1 , se[ls] = inf , cov[ls] = cov[x] , add[ls] = 0;
  25. mn[rs] = cov[x] , mc[rs] = r - mid , se[rs] = inf , cov[rs] = cov[x] , add[rs] = 0;
  26. cov[x] = -1;
  27. }
  28. if(add[x])
  29. {
  30. mn[ls] += add[x] , se[ls] += add[x] , add[ls] += add[x];
  31. mn[rs] += add[x] , se[rs] += add[x] , add[rs] += add[x];
  32. add[x] = 0;
  33. }
  34. if(mn[ls] < mn[x]) mn[ls] = mn[x];
  35. if(mn[rs] < mn[x]) mn[rs] = mn[x];
  36. }
  37. void build(int l , int r , int x)
  38. {
  39. cov[x] = -1;
  40. if(l == r)
  41. {
  42. scanf("%lld" , &mn[x]) , mc[x] = 1 , se[x] = inf;
  43. return;
  44. }
  45. int mid = (l + r) >> 1;
  46. build(lson) , build(rson);
  47. pushup(x);
  48. }
  49. void cover(int b , int e , ll c , int l , int r , int x)
  50. {
  51. if(b <= l && r <= e)
  52. {
  53. mn[x] = c , mc[x] = r - l + 1 , se[x] = inf , cov[x] = c , add[x] = 0;
  54. return;
  55. }
  56. pushdown(l , r , x);
  57. int mid = (l + r) >> 1;
  58. if(b <= mid) cover(b , e , c , lson);
  59. if(e > mid) cover(b , e , c , rson);
  60. pushup(x);
  61. }
  62. void update(int b , int e , ll a , int l , int r , int x)
  63. {
  64. if(b <= l && r <= e)
  65. {
  66. mn[x] += a , se[x] += a , add[x] += a;
  67. return;
  68. }
  69. pushdown(l , r , x);
  70. int mid = (l + r) >> 1;
  71. if(b <= mid) update(b , e , a , lson);
  72. if(e > mid) update(b , e , a , rson);
  73. pushup(x);
  74. }
  75. void vmax(int b , int e , int l , int r , int x)
  76. {
  77. if(mn[x] >= 0) return;
  78. if(b <= l && r <= e && se[x] > 0)
  79. {
  80. mn[x] = 0;
  81. return;
  82. }
  83. pushdown(l , r , x);
  84. int mid = (l + r) >> 1;
  85. if(b <= mid) vmax(b , e , lson);
  86. if(e > mid) vmax(b , e , rson);
  87. pushup(x);
  88. }
  89. int query(int b , int e , int l , int r , int x)
  90. {
  91. if(b <= l && r <= e) return mn[x] ? 0 : mc[x];
  92. pushdown(l , r , x);
  93. int mid = (l + r) >> 1 , ans = 0;
  94. if(b <= mid) ans += query(b , e , lson);
  95. if(e > mid) ans += query(b , e , rson);
  96. return ans;
  97. }
  98. int main()
  99. {
  100. int n , m , opt , x , y;
  101. ll z;
  102. scanf("%d%d" , &n , &m);
  103. build(1 , n , 1);
  104. while(m -- )
  105. {
  106. scanf("%d%d%d" , &opt , &x , &y);
  107. if(opt == 1) scanf("%lld" , &z) , cover(x , y , z , 1 , n , 1);
  108. if(opt == 2) scanf("%lld" , &z) , update(x , y , z , 1 , n , 1) , vmax(x , y , 1 , n , 1);
  109. if(opt == 3) printf("%d\n" , query(x , y , 1 , n , 1));
  110. }
  111. return 0;
  112. }

【bzoj4355】Play with sequence 线段树区间最值操作的更多相关文章

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

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

  2. HDU 5306 Gorgeous Sequence[线段树区间最值操作]

    Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

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

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

  4. HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)

    HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧) 题意分析 题目大意:一个h*w的公告牌,要在其上贴公告. 输入的是1*wi的w值,这些是公告的尺寸. 贴公告 ...

  5. Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间取摸

    D. The Child and Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...

  6. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  7. UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)

    "Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...

  8. cf834D(dp+线段树区间最值,区间更新)

    题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...

  9. Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模

    D. The Child and Sequence   At the children's day, the child came to Picks's house, and messed his h ...

随机推荐

  1. 20145234黄斐《Java程序设计》实验一—Java开发环境的熟悉(Linux + Eclipse)

    实验步骤 由于实验时间比较紧张,这里只有最终结果的截图 (一)命令行下Java程序开发 (二)Eclipse下Java程序开发.调试 (三)练习 实现求正整数1-N之间所有质数的功能,并进行测试 实验 ...

  2. 【SQLSERVER】递归查询算法实例

    一.递归查询 1.结构: 递归CTE最少包含两个查询(也被称为成员). 第一个查询为定点成员,定点成员只是一个返回有效表的查询,用于递归的基础或定位点. 第二个查询被称为递归成员,使该查询称为递归成员 ...

  3. Windows server 2008 IIS7发布asp.net mvc网站css、js脚本无法访问 问题解决

    今天发布网站遇到一个感到很无语的问题,网站发布成功,浏览网站内容数据显示正常,就是没有样式,试了下脚本也是没有反应,如图效果: 接下来就是一顿苦找原因,检查iis设置.什么应用程序池.文件路径等各种检 ...

  4. python4 - 字典

    字典 定义:字典是无序的,它不能通过偏移来存取,只能通过键来存取. 特点:内部没有顺序,通过键来读取内容,可嵌套,方便我们组织多种数据结构,并且可以原地修改里面的内容,属于可变类型. 创建字典.{}, ...

  5. Selenide 阶段性总结介绍(UI自动化测试工具)

    今天给大家介绍一个比较新的UI自动化测试工具-- Selenide.确实是比较新的,国内应该还没有多少人用它.在百度和google上你只能搜到一个中文帖子简单介绍了一下.如果你想用这个工具,不可避免的 ...

  6. 自动化运维工具saltstack02 -- 之SaltStack的配置管理

    SaltStack的配置管理 1.配置管理说明 配置管理,顾名思义及配置与管理, salt-master的配置文件编写格式之YAML语法说明: 数据的结构通过缩进来表示,每一级用两个空格来表示缩进,如 ...

  7. python程序设计——面向对象程序设计:属性

    python 3.x 的属性 可以将属性设置为 可读,可修改,可删除 # 只读属性,不允许修改和删除 class Test: def __init__(self,value): self.__valu ...

  8. PLSQL事务

    1 使用set transaction设置事务属性 2 只读事务 set transaction read only 3 读写事务 set transaction write; 4 在进行数据统计分析 ...

  9. 使用Firebug或chrome-devToolBar深入学习javascript语言核心

    使用Firebug和chrome-devToolBar调试页面样式或脚本是前端开发每天必做之事.这个开发神器到底能给我们带来哪些更神奇的帮助呢?这几天看的一些资料中给了我启发,能不通过Firebug和 ...

  10. elasticsearch备份与恢复

    备注:以下代码在kibana插件下运行: # 创建一个备份用的仓库# type:fs文件系统# 支持Shared filesystem, Amazon S3, HDFS和Azure #Cloud# l ...