11992 - Fast Matrix Operations
要wa死了,书上的代码没太看懂,就按照自己的想法写的,其中掺杂了书上的一些代码居然不对,唉…… #include <iostream> #include <stack> #include <queue> #include <cstdio> #include <cstdlib> #include <cmath> #include <set> #include <vector> #include <cstring> #include <algorithm> #define INF 0x7fffffff #define N 10010 #define M 1000010 #define LL long long #define mod 95041567 using namespace std; struct node{ int MAX, MIN, ADD, SET, SUM; }; node p; node G[22][M << 2]; int cnt; void pushdown(int i, int rt, int L, int R){ int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L; if(G[i][rt].SET != INF){ G[i][lc].SET = G[i][rc].SET = G[i][rt].SET; G[i][rt].SUM = (R - L + 1) * G[i][rt].SET; G[i][rc].SUM = (R - mid) * G[i][rt].SET; G[i][lc].SUM = (mid + 1 - L) * G[i][rt].SET; G[i][rt].MIN = G[i][rc].MIN = G[i][lc].MIN = G[i][rt].SET; G[i][rt].MAX = G[i][rc].MAX = G[i][lc].MAX = G[i][rt].SET; G[i][rt].SET = INF; G[i][rc].ADD = G[i][lc].ADD = 0; } if(G[i][rt].ADD){ G[i][lc].MIN += G[i][rt].ADD; G[i][lc].MAX += G[i][rt].ADD; G[i][lc].ADD += G[i][rt].ADD; G[i][lc].SUM += G[i][rt].ADD * (mid + 1 - L); G[i][rc].MIN += G[i][rt].ADD; G[i][rc].MAX += G[i][rt].ADD; G[i][rc].ADD += G[i][rt].ADD; G[i][rc].SUM += G[i][rt].ADD * (R - mid); G[i][rt].ADD = 0; } } void maintain(int i, int rt, int L, int R){ if(R <= L) return; int lc = rt << 1, rc = (rt << 1) | 1; G[i][rt].SUM = G[i][lc].SUM + G[i][rc].SUM; G[i][rt].MIN = min(G[i][lc].MIN, G[i][rc].MIN); G[i][rt].MAX = max(G[i][lc].MAX, G[i][rc].MAX); G[i][rt].SUM += G[i][rt].ADD * (R - L + 1); G[i][rt].MIN += G[i][rt].ADD; G[i][rt].MAX += G[i][rt].ADD; } void update(int i,int f, int rt, int L, int R, int y1, int y2, int v){ if(y1 == L && y2 == R){ if(f){ G[i][rt].MAX = G[i][rt].MIN = G[i][rt].SET = v; G[i][rt].SUM = v * (R - L + 1); G[i][rt].ADD = 0; } else{ G[i][rt].ADD += v; G[i][rt].MIN += v; G[i][rt].MAX += v; G[i][rt].SUM += (R - L + 1) * v; } return; } pushdown(i, rt, L, R); int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L; if(y2 <= mid) update(i, f, lc, L, mid, y1, y2, v); else if(y1 > mid) update(i, f, rc, mid + 1, R, y1, y2, v); else{ update(i, f, lc, L, mid, y1, mid, v); update(i, f, rc, mid + 1, R, mid + 1, y2, v); } maintain(i, rt, L, R); } void query(int i, int rt, int L, int R, int y1, int y2){ if(L == y1 && R == y2){ p.MAX = max(p.MAX, G[i][rt].MAX); p.MIN = min(p.MIN, G[i][rt].MIN); p.SUM += G[i][rt].SUM; return; } pushdown(i, rt, L, R); int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L; if(y1 > mid) query(i, rc, mid + 1, R, y1, y2); else if(y2 <= mid) query(i, lc, L, mid, y1, y2); else{ query(i, rc, mid + 1, R, mid + 1, y2); query(i, lc, L, mid, y1 ,mid); } maintain(i, rt, L, R); } int main() { int r, c, q; //freopen("in.txt","r",stdin); while(scanf("%d %d %d", &r, &c, &q) != EOF){ for(int i = 0; i < r; ++i) for(int j = c << 2; j >= 0; -- j) G[i][j].MAX = G[i][j].MIN = G[i][j].ADD = G[i][j].SUM = 0, G[i][j].SET = INF; int f, x1, y1, x2, y2, v; for(int i = 0; i < q; ++ i){ cnt = i; scanf("%d %d %d %d %d", &f, &x1, &y1, &x2, &y2); -- f, -- x1, -- x2, -- y1, -- y2; if(f <= 1){ scanf("%d", &v); for(int j = x1; j <= x2; ++ j) update(j, f, 1, 0, c - 1, y1, y2, v); } else { p.SUM = p.MAX = 0, p.MIN = INF; for(int j = x1; j <= x2; ++ j) query(j, 1, 0, c - 1, y1, y2); printf("%d %d %d\n", p.SUM, p.MIN, p.MAX); } } } return 0; }