[uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)相关的知识,希望对你有一定的参考价值。

题目链接:https://vjudge.net/problem/UVA-11992

题意:n*m的矩阵,每次对一个子矩阵操作,有三种操作:加x,设置为x,查询。查询返回子矩阵和、最小值、最大值

n很小(<=20),所以可以开20棵线段树,每次操作按行更新。

特别小心put和add两个延迟标记,坑老惨了。

put初始化-1最简单的坑,略过。

build的时候要每一个节点都要clear,不能只clear叶子。因为会有直接差没操作的子矩阵(因为初始化都是0)。

数组开大。。。

add的话,什么都不用管。

put的话,在update的时候要把那时候的add标记清空,不要忘记在向下传递的时候,也要清空!

上述几点都注意到,这题就能A。感觉写了一道模拟题。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define lrt rt << 1
  5 #define rrt rt << 1 | 1
  6 typedef struct Node {
  7     int lo, hi, sum;
  8     int add, put;
  9 }Node;
 10 const int maxn = 22;
 11 const int maxm = 200200;
 12 Node seg[maxn][maxm<<2];
 13 int n, m, q;
 14 
 15 void pushup(Node* seg, int rt) {
 16     seg[rt].sum = seg[lrt].sum + seg[rrt].sum;
 17     seg[rt].lo = min(seg[lrt].lo, seg[rrt].lo);
 18     seg[rt].hi = max(seg[lrt].hi, seg[rrt].hi);
 19 }
 20 
 21 void pushdown(Node* seg, int rt, int l, int r) {
 22     int mid = (l + r) >> 1;
 23     if(seg[rt].put != -1) {
 24         seg[lrt].sum = (mid - l + 1) * seg[rt].put;
 25         seg[rrt].sum = (r - mid) * seg[rt].put;
 26         seg[lrt].lo = seg[lrt].hi = seg[rt].put;
 27         seg[rrt].lo = seg[rrt].hi = seg[rt].put;
 28         seg[lrt].put = seg[rrt].put = seg[rt].put;
 29         seg[lrt].add = seg[rrt].add = 0;
 30         seg[rt].put = -1;
 31     }
 32     if(seg[rt].add) {
 33         seg[lrt].sum += (mid - l + 1) * seg[rt].add;
 34         seg[rrt].sum += (r - mid) * seg[rt].add;
 35         seg[lrt].lo += seg[rt].add;
 36         seg[lrt].hi += seg[rt].add;
 37         seg[rrt].lo += seg[rt].add;
 38         seg[rrt].hi += seg[rt].add;
 39         seg[lrt].add += seg[rt].add;
 40         seg[rrt].add += seg[rt].add;
 41         seg[rt].add = 0;
 42     }
 43 }
 44 
 45 void build(Node* seg, int l, int r, int rt) {
 46     seg[rt].lo = seg[rt].hi = seg[rt].sum = seg[rt].add = 0;
 47     seg[rt].put = -1;
 48     if(l == r) return;
 49     int mid = (l + r) >> 1;
 50     build(seg, l, mid, lrt);
 51     build(seg, mid+1, r, rrt);
 52 }
 53 
 54 void update(Node* seg, int L, int R, int l, int r, int rt, int val, int type) {
 55     if(L <= l && r <= R) {
 56         if(type == 1) {
 57             seg[rt].lo += val;
 58             seg[rt].hi += val;
 59             seg[rt].add += val;
 60             seg[rt].sum += (r - l + 1) * val;
 61         }
 62         else if(type == 2) {
 63             seg[rt].lo = val;
 64             seg[rt].hi = val;
 65             seg[rt].put = val;
 66             seg[rt].sum = (r - l + 1) * val;
 67             seg[rt].add = 0;
 68         }
 69         return;
 70     }
 71     pushdown(seg, rt, l, r);
 72     int mid = (l + r) >> 1;
 73     if(L <= mid) update(seg, L, R, l, mid, lrt, val, type);
 74     if(mid < R) update(seg, L, R, mid+1, r, rrt, val, type);
 75     pushup(seg, rt);
 76 }
 77 
 78 Node query(Node* seg, int L, int R, int l, int r, int rt) {
 79     if(L <= l && r <= R) return seg[rt];
 80     pushdown(seg, rt, l, r);
 81     int mid = (l + r) >> 1;
 82     Node ret;
 83     ret.lo = 0x7f7f7f7f, ret.hi = 0, ret.sum = 0;
 84     if(L <= mid) {
 85         Node tmp = query(seg, L, R, l, mid, lrt);
 86         ret.lo = min(ret.lo, tmp.lo);
 87         ret.hi = max(ret.hi, tmp.hi);
 88         ret.sum += tmp.sum;
 89     }
 90     if(mid < R) {
 91         Node tmp = query(seg, L, R, mid+1, r, rrt);
 92         ret.lo = min(ret.lo, tmp.lo);
 93         ret.hi = max(ret.hi, tmp.hi);
 94         ret.sum += tmp.sum;
 95     }
 96     pushup(seg, rt);
 97     return ret;
 98 }
 99 
100 int main() {
101     // freopen("in", "r", stdin);
102     // freopen("out", "w", stdout);
103     int type, x1, y1, x2, y2, val;
104     while(~scanf("%d%d%d",&n,&m,&q)) {
105         for(int i = 1; i <= n; i++) {
106             build(seg[i], 1, m, 1);
107         }
108         while(q--) {
109             scanf("%d%d%d%d%d",&type,&x1,&y1,&x2,&y2);
110             if(type == 3) {
111                 Node ret, tmp;
112                 ret.lo = 0x7f7f7f7f, ret.hi = 0, ret.sum = 0;
113                 for(int i = x1; i <= x2; i++) {
114                     tmp = query(seg[i], y1, y2, 1, m, 1);
115                     ret.lo = min(ret.lo, tmp.lo);
116                     ret.hi = max(ret.hi, tmp.hi);
117                     ret.sum += tmp.sum;
118                 }
119                 printf("%d %d %d\n", ret.sum, ret.lo, ret.hi);
120             }
121             else {
122                 scanf("%d", &val);
123                 for(int i = x1; i <= x2; i++) {
124                     update(seg[i], y1, y2, 1, m, 1, val, type);
125                 }
126             }
127         }
128     }
129     return 0;
130 }

 

以上是关于[uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)的主要内容,如果未能解决你的问题,请参考以下文章

UVA11992 Fast Matrix Operations

luogu题解 UVA11992 Fast Matrix Operations

[uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)

题解 UVA11992 Fast Matrix Operations

UVA - 11992 线段树

[Hdoj] Fast Matrix Calculation