[BZOJ1582] [Usaco2009 Hol]Holiday Painting 节日画画(线段树)
线段树区间修改傻题
#include <cstdio> #include <cstring> #include <iostream> #define N 50001 #define root 1, 1, n #define ls now << 1, l, mid #define rs now << 1 | 1, mid + 1, r int n, m, q, res; int ans[16][N << 2], sum[16][N][2], add[16][N << 2]; char s[N]; //sum[i][j]表示第i列前j个中0的个数 inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline void build(int id, int now, int l, int r) { if(l == r) { ans[id][now] = sum[id][l][0] - sum[id][l - 1][0]; return; } int mid = (l + r) >> 1; build(id, ls); build(id, rs); ans[id][now] = ans[id][now << 1] + ans[id][now << 1 | 1]; } inline void push_down(int id, int now, int l, int r) { if(add[id][now] ^ -1) { int mid = (l + r) >> 1; add[id][now << 1] = add[id][now]; add[id][now << 1 | 1] = add[id][now]; ans[id][now << 1] = sum[id][mid][add[id][now]] - sum[id][l - 1][add[id][now]]; ans[id][now << 1 | 1] = sum[id][r][add[id][now]] - sum[id][mid][add[id][now]]; add[id][now] = -1; } } inline void update(int id, int now, int l, int r, int x, int y, int c) { if(x <= l && r <= y) { add[id][now] = c; ans[id][now] = sum[id][r][c] - sum[id][l - 1][c]; return; } push_down(id, now, l, r); int mid = (l + r) >> 1; if(x <= mid) update(id, ls, x, y, c); if(mid < y) update(id, rs, x, y, c); ans[id][now] = ans[id][now << 1] + ans[id][now << 1 | 1]; } int main() { int i, j, r1, r2, c1, c2, x; n = read(); m = read(); q = read(); for(i = 1; i <= n; i++) { scanf("%s", s + 1); for(j = 1; j <= m; j++) { sum[j][i][0] = sum[j][i - 1][0] + (s[j] == '0'); sum[j][i][1] = sum[j][i - 1][1] + (s[j] == '1'); } } for(i = 1; i <= m; i++) build(i, root); memset(add, -1, sizeof(add)); while(q--) { r1 = read(); r2 = read(); c1 = read(); c2 = read(); x = read(); res = 0; for(i = c1; i <= c2; i++) update(i, root, r1, r2, x); for(i = 1; i <= m; i++) res += ans[i][1]; printf("%d\n", res); } return 0; }