题意:对一个矩阵进行子矩阵操作。

元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作。

一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测没有),如果判断一下然后启发式建树复杂度是min(RlogC,ClogR)。

代码中结点没有保存l和r,而且询问是保存在全局变量中,这样做比较省空间。但是也有缺点,比如推区间结点数量的时候会麻烦一点。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int maxn = 1e6+;
  5. int R,C;
  6.  
  7. #define lid (id<<1)
  8. #define rid (id<<1|1)
  9. struct Seg
  10. {
  11. int add,setv;
  12. int Max,Min,sum;
  13. }tr[maxn<<];
  14.  
  15. #define OP1(id,val)\
  16. tr[id].add += val; tr[id].Max += val; tr[id].Min += val; tr[id].sum += (r-l+)*val;
  17. #define OP2(id,val)\
  18. tr[id].Max = tr[id].setv = tr[id].Min = val; tr[id].add = ; tr[id].sum = val*(r-l+);
  19.  
  20. inline void push_down(int id,int l,int r)
  21. {
  22. int lc = lid, rc = rid, mid = (l+r)>>;
  23. if(tr[id].setv>=){
  24. int &t = tr[id].setv;
  25. swap(r,mid);
  26. OP2(lc,t);
  27. swap(l,r); l++; swap(mid,r);
  28. OP2(rc,t);
  29. l--; swap(mid,l);
  30. t = -;
  31. }
  32. if(tr[id].add>){
  33. int &t = tr[id].add;
  34. swap(r,mid);
  35. OP1(lc,t);
  36. swap(l,r); l++; swap(mid,r);
  37. OP1(rc,t);
  38. l--; swap(mid,l);
  39. t = ;
  40. }
  41. }
  42.  
  43. inline void maintain(int id)
  44. {
  45. int lc = lid, rc = rid;
  46. tr[id].sum = tr[lc].sum + tr[rc].sum;
  47. tr[id].Max = max(tr[lc].Max,tr[rc].Max);
  48. tr[id].Min = min(tr[lc].Min,tr[rc].Min);
  49. }
  50.  
  51. int ql,qr,val;
  52. void add1D(int l = ,int r = R*C-,int id = )
  53. {
  54. if(ql<=l&&r<=qr) { OP1(id,val) return; }
  55. int mid = (l+r)>>, lc = lid, rc = rid;
  56. push_down(id,l,r);
  57. if(ql<=mid) add1D(l,mid,lc);
  58. if(qr>mid) add1D(mid+,r,rc);
  59. maintain(id);
  60. }
  61.  
  62. void set1D(int l = ,int r = R*C-,int id = )
  63. {
  64. if(ql<=l&&r<=qr) { OP2(id,val) return; }
  65. int mid = (l+r)>>, lc = lid, rc = rid;
  66. push_down(id,l,r);
  67. if(ql<=mid) set1D(l,mid,lc);
  68. if(qr>mid) set1D(mid+,r,rc);
  69. maintain(id);
  70. }
  71.  
  72. int queryMax1D(int l = ,int r = R*C-,int id = )
  73. {
  74. if(ql<=l&&r<=qr) { return tr[id].Max; }
  75. int mid = (l+r)>>, lc = lid, rc = rid;
  76. push_down(id,l,r);
  77. int ret = ;
  78. if(ql<=mid) ret = max(ret,queryMax1D(l,mid,lc));
  79. if(qr>mid) ret = max(ret,queryMax1D(mid+,r,rc));
  80. return ret;
  81. }
  82.  
  83. const int INF = 0x3f3f3f3f;
  84.  
  85. int queryMin1D(int l = ,int r = R*C-,int id = )
  86. {
  87. if(ql<=l&&r<=qr) { return tr[id].Min; }
  88. int mid = (l+r)>>, lc = lid, rc = rid;
  89. push_down(id,l,r);
  90. int ret = INF;
  91. if(ql<=mid) ret = min(ret,queryMin1D(l,mid,lc));
  92. if(qr>mid) ret = min(ret,queryMin1D(mid+,r,rc));
  93. return ret;
  94. }
  95.  
  96. int querySum1D(int l = ,int r = R*C-,int id = )
  97. {
  98. if(ql<=l&&r<=qr) { return tr[id].sum; }
  99. int mid = (l+r)>>, lc = lid, rc = rid;
  100. push_down(id,l,r);
  101. int ret = ;
  102. if(ql<=mid) ret += querySum1D(l,mid,lc);
  103. if(qr>mid) ret += querySum1D(mid+,r,rc);
  104. return ret;
  105. }
  106.  
  107. //[0,r)
  108. void add2D(int x1,int y1,int x2,int y2,int v)
  109. {
  110. val = v;
  111. int st = x1*C+y1, len = y2-y1;
  112. for(int x = x1; x <= x2; x++){
  113. ql = st; qr = st+len;
  114. add1D();
  115. st += C;
  116. }
  117. }
  118.  
  119. void set2D(int x1,int y1,int x2,int y2,int v)
  120. {
  121. val = v;
  122. int st = x1*C+y1, len = y2-y1;
  123. for(int x = x1; x <= x2; x++){
  124. ql = st; qr = st+len;
  125. set1D();
  126. st += C;
  127. }
  128. }
  129.  
  130. int querySum2D(int x1,int y1,int x2,int y2)
  131. {
  132. int ret = ;
  133. int st = x1*C+y1, len = y2-y1;
  134. for(int x = x1; x <= x2; x++){
  135. ql = st; qr = st+len;
  136. ret += querySum1D();
  137. st += C;
  138. }
  139. return ret;
  140. }
  141.  
  142. int queryMax2D(int x1,int y1,int x2,int y2)
  143. {
  144. int ret = ;
  145. int st = x1*C+y1, len = y2-y1;
  146. for(int x = x1; x <= x2; x++){
  147. ql = st; qr = st+len;
  148. ret = max(ret,queryMax1D());
  149. st += C;
  150. }
  151. return ret;
  152. }
  153.  
  154. int queryMin2D(int x1,int y1,int x2,int y2)
  155. {
  156. int ret = INF;
  157. int st = x1*C+y1, len = y2-y1;
  158. for(int x = x1; x <= x2; x++){
  159. ql = st; qr = st+len;
  160. ret = min(ret,queryMin1D());
  161. st += C;
  162. }
  163. return ret;
  164. }
  165.  
  166. int main()
  167. {
  168. //freopen("in.txt","r",stdin);
  169. int m;
  170. while(~scanf("%d%d%d",&R,&C,&m)){
  171. ql = ; qr = R*C-; val = ;
  172. set1D();
  173. while(m--){
  174. int op,x1,y1,x2,y2; scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
  175. if(op == ){
  176. int v; scanf("%d",&v);
  177. add2D(x1-,y1-,x2-,y2-,v);
  178. }else if(op == ){
  179. int v; scanf("%d",&v);
  180. set2D(x1-,y1-,x2-,y2-,v);
  181. }else {
  182. x1--;x2--;y1--;y2--;
  183. printf("%d %d %d\n",querySum2D(x1,y1,x2,y2),queryMin2D(x1,y1,x2,y2),queryMax2D(x1,y1,x2,y2));
  184. }
  185. }
  186. }
  187. return ;
  188. }

UVA 11992 Fast Matrix Operations (降维)的更多相关文章

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

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

  2. uva 11992 Fast Matrix Operations 线段树模板

    注意 setsetset 和 addvaddvaddv 标记的下传. 我们可以控制懒惰标记的优先级. 由于 setsetset 操作的优先级高于 addaddadd 操作,当下传 setsetset ...

  3. UVA 11992 Fast Matrix Operations(线段树:区间修改)

    题目链接 2015-10-30 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=s ...

  4. 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations

    题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...

  5. UVA 11992 Fast Matrix Operations (二维线段树)

    解法:因为至多20行,所以至多建20棵线段树,每行建一个.具体实现如下,有些复杂,慢慢看吧. #include <iostream> #include <cstdio> #in ...

  6. uva 11992 - Fast Matrix Operations

    简单的线段树的题: 有两种方法写这个题,目前用的熟是这种慢点的: 不过不知道怎么老是T: 感觉网上A过的人的时间度都好小,但他们都是用数组实现的 难道是指针比数组慢? 好吧,以后多用数组写写吧! 超时 ...

  7. UVa 11992 Fast Matrix Operations (线段树,区间修改)

    题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...

  8. 【UVA】11992 - Fast Matrix Operations(段树模板)

    主体段树,要注意,因为有set和add操作,当慵懒的标志下推.递归优先set,后复发add,每次运行set行动add马克清0 WA了好几次是由于计算那一段的时候出问题了,可笑的是我对着模板找了一个多小 ...

  9. Fast Matrix Operations(UVA)11992

    UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y ...

随机推荐

  1. 2.5玩转xargs

    我们可以利用管道将一个命令的stdout(标准输出)重定向到另一个命令的stdin(标准输入).有些命令只能以命令行参数的形式接受数据,而无法通过stdin接受数据流.这时候就没法使用管道.那么xar ...

  2. NativeScript官方书籍:1.为什么选择nativescript

    1.为什么选择nativescript 本章介绍 什么是NativeScript nativescript对于移动开发世界意味着什么 NativeScript工作原理 在早期的移动应用程序(前iPho ...

  3. HDU - 5887 2016青岛网络赛 Herbs Gathering(形似01背包的搜索)

    Herbs Gathering 10.76% 1000ms 32768K   Collecting one's own plants for use as herbal medicines is pe ...

  4. WebView根据加载的内容来控制其高度

    一.先设置WebView的高度为0,然后在其加载结束后的代理方法中根据contentSize设置其高度 //初始话一个UIWebView: self.webView = [[[UIWebView al ...

  5. SCUT - 12 - 西方国家 - 矩阵快速幂

    https://scut.online/p/12 可以用矩阵快速幂来做. #include<bits/stdc++.h> using namespace std; typedef long ...

  6. Solr 6.7学习笔记(02)-- 配置文件 managed-schema (schema.xml) - Analyzer, tokenizer(4)

    有些时候,我们需要自定义 fieldType.下面的例子就是自定义的 fieldType,<analyzer type="index"> 表示索引时怎么处理,<a ...

  7. python unittest模块

    import unittest import random class Operation(object): def __init__(self, num1=0, num2=0): if not (0 ...

  8. uoj#280. 【UTR #2】题目难度提升(构造)

    传送门 咱先膜一下\(GXZ\)再说 我们先把序列从小到大排序,然后分情况讨论 无解是不存在的,从小到大输出所有数肯定可行 情况一,如果\(a[mid]=a[mid+1]\),因为最终的中位数也是它们 ...

  9. 洛谷P4770 [NOI2018]你的名字(后缀自动机+线段树)

    传送门 我有种自己根本没学过SAM的感觉……最后还是抄了老半天的题解…… 首先,对$S$和每一次的$T$都建一个SAM 先考虑一下$l=1,r=\left| S \right|$的情况 设$lim_i ...

  10. 有关xerosploit运行报错问题的有效解决方案

    [安装xerosploit]安装xerosploit的步骤如下,我是将xerosploit直接克隆到了根目录下(使用“cd /”到达根目录) git clone https://github.com/ ...