这个题目要求和 还有 设置区间值 区间增值,明显要用线段树来

由于行数不超过20 而列数多达 10^5,所以对每一行建一棵线段树。

然后主要是在懒惰标记方面是难点 针对两种操作 分别设置 set 和 add 方法,但是优先级方面要好好考虑

可能出现的结果无非是 单独的 set 或者 add  以及 先set再add  或者 先add再set,单独的那两种就按常规写法,然后先set再add,则明显 add标记不能清除set,所以在pushdown的时候 先set 再 add,先set 再add ,则直接清除当前的add标记,在pushdown的时候同样清除子节点的add标记

其实只要搞清优先级 也挺简单的。。。懒惰标记用的还不熟练,要继续加强

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #define lson rt<<1,l,mid
  5. #define rson rt<<1|1,mid+1,r
  6. using namespace std;
  7. const int N = +;
  8. int d[][N*],dmax[][N*],dmin[][N*],setv[][N*],addv[][N*];
  9. int r,c,m;
  10. struct node
  11. {
  12. int tot,maxn,mini;
  13. };
  14. void up(int num,int rt)
  15. {
  16. d[num][rt]=d[num][rt<<]+d[num][rt<<|];
  17. dmax[num][rt]=max(dmax[num][rt<<],dmax[num][rt<<|]);
  18. dmin[num][rt]=min(dmin[num][rt<<],dmin[num][rt<<|]);
  19. }
  20. void build(int num,int rt,int l,int r)
  21. {
  22. setv[num][rt]=-;
  23. addv[num][rt]=;
  24. d[num][rt]=dmax[num][rt]=dmin[num][rt]=;
  25. if (l>=r){
  26. return;
  27. }
  28. int mid=(l+r)>>;
  29. build(num,lson);
  30. build(num,rson);
  31. }
  32. void pushdown(int num,int rt,int l,int r)
  33. {
  34. if (l>=r) return;
  35. int mid=(l+r)>>;
  36. if (setv[num][rt]>=){
  37. d[num][rt<<]=(mid-l+)*setv[num][rt];
  38. dmax[num][rt<<]=setv[num][rt];
  39. dmin[num][rt<<]=setv[num][rt];
  40.  
  41. d[num][rt<<|]=(r-mid)*setv[num][rt];
  42. dmax[num][rt<<|]=setv[num][rt];
  43. dmin[num][rt<<|]=setv[num][rt];
  44.  
  45. setv[num][rt<<]=setv[num][rt<<|]=setv[num][rt];
  46. setv[num][rt]=-;
  47. addv[num][rt<<]=addv[num][rt<<|]=;
  48. }
  49. if (addv[num][rt]){
  50. d[num][rt<<]+=(mid-l+)*addv[num][rt];
  51. dmax[num][rt<<]+=addv[num][rt];
  52. dmin[num][rt<<]+=addv[num][rt];
  53.  
  54. d[num][rt<<|]+=(r-mid) *addv[num][rt];
  55. dmax[num][rt<<|]+=addv[num][rt];
  56. dmin[num][rt<<|]+=addv[num][rt];
  57.  
  58. addv[num][rt<<]+=addv[num][rt];
  59. addv[num][rt<<|]+=addv[num][rt];
  60. addv[num][rt]=;
  61. }
  62. }
  63. void pushdown2(int num,int rt,int l,int r)
  64. {
  65. if (l>=r) return;
  66. int mid=(l+r)>>;
  67. if (setv[num][rt]>=){
  68. d[num][rt<<]=(mid-l+)*setv[num][rt];
  69. dmax[num][rt<<]=setv[num][rt];
  70. dmin[num][rt<<]=setv[num][rt];
  71.  
  72. d[num][rt<<|]=(r-mid)*setv[num][rt];
  73. dmax[num][rt<<|]=setv[num][rt];
  74. dmin[num][rt<<|]=setv[num][rt];
  75.  
  76. setv[num][rt<<]=setv[num][rt<<|]=setv[num][rt];
  77. setv[num][rt]=-;
  78. addv[num][rt<<]=addv[num][rt<<|]=;
  79. }
  80. if (addv[num][rt]){
  81. d[num][rt<<]+=(mid-l+)*addv[num][rt];
  82. dmax[num][rt<<]+=addv[num][rt];
  83. dmin[num][rt<<]+=addv[num][rt];
  84.  
  85. d[num][rt<<|]+=(r-mid) *addv[num][rt];
  86. dmax[num][rt<<|]+=addv[num][rt];
  87. dmin[num][rt<<|]+=addv[num][rt];
  88.  
  89. addv[num][rt<<]+=addv[num][rt];
  90. addv[num][rt<<|]+=addv[num][rt];
  91. addv[num][rt]=;
  92. }
  93. }
  94.  
  95. void add(int num,int v,int L,int R,int rt,int l,int r)
  96. {
  97.  
  98. if (L<=l && r<=R){
  99. d[num][rt]+=v*(r-l+);
  100. dmax[num][rt]+=v;
  101. dmin[num][rt]+=v;
  102. addv[num][rt]+=v;
  103. return;
  104. }
  105. pushdown(num,rt,l,r);
  106. int mid=(l+r)>>;
  107. if (L<=mid) add(num,v,L,R,lson);
  108. if (R>mid) add(num,v,L,R,rson);
  109. up(num,rt);
  110. }
  111. void sets(int num,int v,int L,int R,int rt,int l,int r)
  112. {
  113.  
  114. if (L<=l && r<=R){
  115. d[num][rt]=v*(r-l+);
  116. dmax[num][rt]=v;
  117. dmin[num][rt]=v;
  118. setv[num][rt]=v;
  119. addv[num][rt]=; //set标记直接清除当前的add标记 这里要注意别漏掉
  120. return;
  121. }
  122. pushdown(num,rt,l,r);
  123. int mid=(l+r)>>;
  124. if (L<=mid) sets(num,v,L,R,lson);
  125. if (R>mid) sets(num,v,L,R,rson);
  126. up(num,rt);
  127. }
  128. node query(int num,int L,int R,int rt,int l,int r)
  129. {
  130. int mid=(l+r)>>;
  131. pushdown2(num,rt,l,r);
  132. if (L<=l && r<=R){
  133. node tmp=(node){d[num][rt],dmax[num][rt],dmin[num][rt]};
  134. return tmp;
  135. }
  136. node t1=(node){-,,};
  137. node t2=(node){-,,};
  138. if (L<=mid) t1=query(num,L,R,lson);
  139. if (R>mid) t2=query(num,L,R,rson);
  140. if (t1.tot<) return t2;
  141. if (t2.tot<) return t1;
  142. t1.tot+=t2.tot;
  143. t1.maxn=max(t2.maxn,t1.maxn);
  144. t1.mini=min(t1.mini,t2.mini);
  145. return t1;
  146.  
  147. }
  148. int main()
  149. {
  150. while (scanf("%d%d%d",&r,&c,&m)!=EOF)
  151. {
  152. for (int i=;i<r;i++){
  153. build(i,,,c);
  154. }
  155. while (m--){
  156. int deno,x1,y1,x2,y2,v;
  157. scanf("%d",&deno);
  158. if (deno<=){
  159. scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&v);
  160. x1--;x2--;
  161. for (int i=x1;i<=x2;i++){
  162. if (deno==) add(i,v,y1,y2,,,c);
  163. else sets(i,v,y1,y2,,,c);
  164. }
  165. }
  166. else{
  167. scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
  168. x1--;x2--;
  169. node ans;
  170. for (int i=x1;i<=x2;i++){
  171. if (i==x1) ans=query(i,y1,y2,,,c);
  172. else {
  173. node tmp=query(i,y1,y2,,,c);
  174. ans.tot+=tmp.tot;
  175. ans.maxn=max(tmp.maxn,ans.maxn);
  176. ans.mini=min(tmp.mini,ans.mini);
  177. }
  178. }
  179. printf("%d %d %d\n",ans.tot,ans.mini,ans.maxn);
  180. }
  181. }
  182. }
  183. return ;
  184. }

UVA 11992 懒惰标记应用的更多相关文章

  1. 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)

    题目0到n-1的花瓶,操作1在下标a开始插b朵花,输出始末下标.操作2清空[a,b]的花瓶,求清除的花的数量.线段树懒惰标记来更新区间.操作1,先查询0到a-1有num个空瓶子,然后用线段树的性质,或 ...

  2. bzoj1251 序列终结者(Splay Tree+懒惰标记)

    Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...

  3. 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  4. 【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

  5. UVA 11992 - Fast Matrix Operations(段树)

    UVA 11992 - Fast Matrix Operations 题目链接 题意:给定一个矩阵,3种操作,在一个矩阵中加入值a,设置值a.查询和 思路:因为最多20列,所以全然能够当作20个线段树 ...

  6. poj3468 线段树的懒惰标记

    题目链接:poj3468 题意:给定一段数组,有两种操作,一种是给某段区间加c,另一种是查询一段区间的和 思路:暴力的方法是每次都给这段区间的点加c,查询也遍历一遍区间,复杂度是n*n,肯定过不去,另 ...

  7. FZU-1608 Huge Mission 线段树(更新懒惰标记)

    题目链接: https://cn.vjudge.net/problem/FZU-1608 题目大意: 长度n,m次操作:每次操作都有三个数:a,b,c:意味着(a,b]区间单位长度的价值为c,若某段长 ...

  8. hdu1698 Just a Hook (线段树区间更新 懒惰标记)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. HDU 4107 Gangster(线段树 特殊懒惰标记)

    两种做法. 第一种:标记区间最大值和最小值,若区间最小值>=P,则本区间+2c,若区间最大值<P,则本区间+c.非常简单的区间更新. 最后发一点牢骚:最后query查一遍就行,我这个2B竟 ...

随机推荐

  1. Java并发编程之并发简介

    操作系统中同时执行多个程序原因: 1.资源利用率:系统资源及硬件资源.当一个程序再等待另一个程序时,可以运行另一个程序,可提高资源利用率. 2.公平性:多个程序对计算机上的资源理论上具有同等的使用权. ...

  2. [noip2014]P2312 解方程

    P2312 解方程 其实这道题就是求一个1元n次方程在区间[1, m]上的整数解. 我们枚举[1, m]上的所有整数,带进多项式中看看结果是不是0即可. 这里有一个技巧就是秦九韶算法,请读者自行查看学 ...

  3. MIT课程

    8.02  Physics II (电磁学基础) Introduction to electromagnetism and electrostatics: electric charge, Coulo ...

  4. springCloud 之 Eureka注册中心高可用配置

    springCloud的eureka高可用配置方案思路是:几个服务中心之间相互注册,比如两个注册中心,A注册到B上,B注册到A上,如果是三个注册中心则是:A注册到BC上,B注册到AC上,C注册到AB上 ...

  5. 关于ESP8266和ESP8285的对比

    ESP8285=ESP8266+1M Flash. 与ESP8266相比,其能耐高温达125摄氏度!且原有ESP8266源码程序可以原封不动移植使用.ESP-M1/M2 模块核心处理器采用高性价比芯片 ...

  6. 习题两则的简化(利用for循环)

    习题一.打印26个英文字母 public class PrintChars { public static void main(String[] args) { char ch = 'a'; int ...

  7. 031.SAP上查看所有的用户账号,查询SAP用户账号的后台数据库表

    01. 输入事务代码SU11, 然后输入SAP用户账号数据表USER_ADDR 02. 点击实用程序,再点击内容 03.点击查询 04. 将查看到的结果通过Excel表格导出 不忘初心,如果您认为这篇 ...

  8. U盘启动盘空间变小

    Windows下管理员身份运行cmd,调用diskpart,约5秒进入程序 磁盘管理中新建卷. 建议使用Rufus制作U盘启动盘.

  9. spark aggregate算子

    spark aggregate源代码 /** * Aggregate the elements of each partition, and then the results for all the ...

  10. Java线程池 ThreadPoolExecutor类

    什么是线程池? java线程池是将大量的线程集中管理的类, 包括对线程的创建, 资源的管理, 线程生命周期的管理. 当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程, 从而减少系 ...