练基本功 成段更新求2维区间最大值最小值以及和 把某个区间置为v 把某个区间都加上v
难点是set与add的先后顺序的处理
如果先做add在做set那么add是没用的 所以做set时将add置为0
当add不为0 并且 set不为0 那么set肯定在add前面(如果在后面 那么add就置为0了)所以这种情况先做set
当add为0 set不为0 肯定要做set
当add不为0 set为0 做add
都为0(做他干嘛)
所以 按照先set 在add的顺序满足上诉实况
不知小弟理解是否有错
望各位大哥不吝赐教
#include <cstdio> #include <cstring> #include <vector> using namespace std; const int maxn = 1000010; struct node { int l; int r; int max_val; int min_val; int sum; int addv; int setv; }; node a[22][maxn<<2], p; void pushup(int i, int rt) { a[i][rt].sum = a[i][rt<<1].sum + a[i][rt<<1|1].sum; a[i][rt].max_val = max(a[i][rt<<1].max_val, a[i][rt<<1|1].max_val); a[i][rt].min_val = min(a[i][rt<<1].min_val, a[i][rt<<1|1].min_val); } void pushdown(int i, int rt) { int k = a[i][rt].r - a[i][rt].l + 1; if(a[i][rt].setv != -1) { a[i][rt<<1].setv = a[i][rt<<1|1].setv = a[i][rt].setv; a[i][rt<<1].min_val = a[i][rt<<1|1].min_val = a[i][rt].setv; a[i][rt<<1].max_val = a[i][rt<<1|1].max_val = a[i][rt].setv; a[i][rt<<1].sum = a[i][rt].setv * (k - (k >> 1)); a[i][rt<<1|1].sum = a[i][rt].setv * (k >> 1); a[i][rt].setv = -1; a[i][rt<<1].addv = 0; a[i][rt<<1|1].addv = 0; } if(a[i][rt].addv) { a[i][rt<<1].addv += a[i][rt].addv; a[i][rt<<1].max_val += a[i][rt].addv; a[i][rt<<1].min_val += a[i][rt].addv; a[i][rt<<1].sum += a[i][rt].addv * (k - (k >> 1)); a[i][rt<<1|1].addv += a[i][rt].addv; a[i][rt<<1|1].max_val += a[i][rt].addv; a[i][rt<<1|1].min_val += a[i][rt].addv; a[i][rt<<1|1].sum += a[i][rt].addv * (k >> 1); a[i][rt].addv = 0; } } void build(int i, int l, int r, int rt) { //printf("%d %d %d %d\n", i, l, r, rt); a[i][rt].sum = 0; a[i][rt].max_val = 0; a[i][rt].min_val = 0; a[i][rt].addv = 0; a[i][rt].setv = -1; a[i][rt].l = l; a[i][rt].r = r; if(l == r) return; int m = (l + r) >> 1; build(i, l, m, rt<<1); build(i, m+1, r, rt<<1|1); } void update(int i, int x, int y, int rt, int v, int key) { if(a[i][rt].l == x && a[i][rt].r == y) { if(key == 1) { a[i][rt].addv += v; a[i][rt].sum += (y-x+1)*v; a[i][rt].max_val += v; a[i][rt].min_val += v; } else { a[i][rt].setv = v; a[i][rt].sum = (y-x+1)*v; a[i][rt].max_val = v; a[i][rt].min_val = v; a[i][rt].addv = 0; } return; } //if(a[i][rt].l == a[i][rt].r) // return; pushdown(i, rt); int m = (a[i][rt].l + a[i][rt].r) >> 1; if(y <= m) update(i, x, y, rt<<1, v, key); else if(x > m) update(i, x, y, rt<<1|1, v, key); else { update(i, x, m, rt<<1, v, key); update(i, m+1, y, rt<<1|1, v, key); } pushup(i, rt); } void query(int i, int x, int y, int rt) { if(a[i][rt].l == x && a[i][rt].r == y) { p.sum += a[i][rt].sum; p.min_val = min(p.min_val, a[i][rt].min_val); p.max_val = max(p.max_val, a[i][rt].max_val); return; } pushdown(i, rt); int m = (a[i][rt].l + a[i][rt].r) >> 1; if(y <= m) query(i, x, y, rt<<1); else if(x > m) query(i, x, y, rt<<1|1); else { query(i, x, m, rt<<1); query(i, m+1, y, rt<<1|1); } pushup(i, rt); } int main() { int n, m, q; while(scanf("%d %d %d", &n, &m, &q) != EOF) { for(int i = 1; i <= n; i++) build(i, 1, m, 1); //puts("s"); /*for(int i = 1; i <= n; ++i) for(int j = m << 2; j >= 0; -- j) a[i][j].max_val = a[i][j].min_val = a[i][j].addv = a[i][j].sum = 0, a[i][j].setv = -1;*/ while(q--) { int k; scanf("%d", &k); if(k == 1) { int x1, y1, x2, y2, v; scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &v); for(int i = x1; i <= x2; i++) update(i, y1, y2, 1, v, 1); } else if(k == 2) { int x1, y1, x2, y2, v; scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &v); for(int i = x1; i <= x2; i++) update(i, y1, y2, 1, v, 2); } else { int x1, y1, x2, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); p.sum = 0; p.max_val = 0; p.min_val = 999999999; for(int i = x1; i <= x2; i++) query(i, y1, y2, 1); printf("%d %d %d\n", p.sum, p.min_val, p.max_val); } } } return 0; }