【扬中集训 DAY4T3】holiday
【题目链接】
【算法】
建C棵线段树即可,注意要用前缀和优化
【代码】
这是标程
#include <bits/stdc++.h> using namespace std; const int MAXR = 50005, MAXC = 17, MAXN = 4 * MAXR + 10; int R, C, Q; int am0[MAXC][MAXR]; char grid[MAXR][MAXC]; bool mark[MAXN]; int am[MAXN][MAXC]; int change[MAXN][MAXC]; inline void split(int at, int l, int r) { mark[at] = false; for (int i = 1; i <= C; ++i) if (change[at][i] < 2) { int got = am0[i][r] - am0[i][l]; if (change[at][i] == 1) got = r - l - got; am[at][i] = got; } if (l + 1 != r) { mark[at * 2 + 1] = true; mark[at * 2 + 2] = true; for (int i = 1; i <= C; ++i) if (change[at][i] < 2) { change[at * 2 + 1][i] = change[at][i]; change[at * 2 + 2][i] = change[at][i]; change[at][i] = 2; } } } void update(int at, int l, int r, int nl, int nr, int cols[]) { if (mark[at]) split(at, l, r); if (l == nl && r == nr) { mark[at] = true; for (int i = 1; i <= C; ++i) if (cols[i] < 2) change[at][i] = cols[i]; split(at, l, r); return; } int m = (l + r) / 2; if (nr <= m) update(at * 2 + 1, l, m, nl, nr, cols); else if (m <= nl) update(at * 2 + 2, m, r, nl, nr, cols); else { update(at * 2 + 1, l, m, nl, m, cols); update(at * 2 + 2, m, r, m, nr, cols); } if (mark[at * 2 + 1]) split(at * 2 + 1, l, m); if (mark[at * 2 + 2]) split(at * 2 + 2, m, r); for (int i = 1; i <= C; ++i) // join am[at][i] = am[at * 2 + 1][i] + am[at * 2 + 2][i]; } void read() { scanf("%d %d %d", &R, &C, &Q); for (int i = 0; i < R; ++i) scanf("%s", grid[i]); } void solve() { for (int i = 1; i <= C; ++i) for (int j = 1; j <= R; ++j) { am0[i][j] = am0[i][j - 1]; if (grid[j - 1][i - 1] == '0') ++am0[i][j]; } int cols[MAXC]; for (int i = 0; i < MAXC; ++i) cols[i] = 0; update(0, 0, R, 0, R, cols); int r1, r2, c1, c2, x; if (mark[0]) split(0, 0, R); for (int i = 0; i < Q; ++i) { scanf("%d %d %d %d %d", &r1, &r2, &c1, &c2, &x); for (int j = 0; j <= C; ++j) if (j >= c1 && j <= c2) cols[j] = x; else cols[j] = 2; update(0, 0, R, r1 - 1, r2, cols); if (mark[0]) split(0, 0, R); int ans = 0; for (int i = 1; i <= C; ++i) ans += am[0][i]; printf("%d\n", ans); } } int main() { read(); solve(); return 0; }
这是我的程序
#include<bits/stdc++.h> using namespace std; #define MAXR 50000 #define MAXC 15 #define MAXQ 1000 struct SegmentTree { int l,r,opt,sum; } tree[MAXC+10][MAXR*4+10]; int i,j,R,C,Q,R1,R2,C1,C2,X,ans; char ch; int mat[MAXR+10][MAXC+10],sum[MAXR+10][MAXC+10]; template <typename T> inline void read(T &x) { int f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; } for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> inline void write(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x/10); putchar(x%10+'0'); } template <typename T> inline void writeln(T x) { write(x); puts(""); } inline void build(int pos,int index,int l,int r) { int mid; tree[pos][index].l = l; tree[pos][index].r = r; tree[pos][index].sum = r - l + 1 - sum[r][pos] + sum[l-1][pos]; tree[pos][index].opt = 0; if (l == r) return; mid = (l + r) >> 1; build(pos,index*2,l,mid); build(pos,index*2+1,mid+1,r); } inline void pushdown(int pos,int index) { int l = tree[pos][index].l, r = tree[pos][index].r; if (l == r) return; tree[pos][index*2].opt = tree[pos][index].opt; tree[pos][index*2+1].opt = tree[pos][index].opt; l = tree[pos][index*2].l, r = tree[pos][index*2].r; if (!tree[pos][index].opt) tree[pos][index*2].sum = r - l + 1 - sum[r][pos] + sum[l-1][pos]; else tree[pos][index*2].sum = sum[r][pos] - sum[l-1][pos]; l = tree[pos][index*2+1].l, r = tree[pos][index*2+1].r; if (!tree[pos][index].opt) tree[pos][index*2+1].sum = r - l + 1 - sum[r][pos] + sum[l-1][pos]; else tree[pos][index*2+1].sum = sum[r][pos] - sum[l-1][pos]; } inline void pushup(int pos,int index) { tree[pos][index].sum = tree[pos][index*2].sum + tree[pos][index*2+1].sum; if ((tree[pos][index*2].opt == -1) || (tree[pos][index*2+1].opt == -1)) { tree[pos][index].opt = -1; return; } if (tree[pos][index*2].opt != tree[pos][index*2+1].opt) { tree[pos][index].opt = -1; return; } tree[pos][index].opt = tree[pos][index*2].opt; } inline void modify(int pos,int index,int l,int r,int val) { int mid; if (tree[pos][index].opt != -1) pushdown(pos,index); if ((tree[pos][index].l == l) && (tree[pos][index].r == r)) { tree[pos][index].opt = val; if (!val) tree[pos][index].sum = r - l + 1 - sum[r][pos] + sum[l-1][pos]; else tree[pos][index].sum = sum[r][pos] - sum[l-1][pos]; } else { mid = (tree[pos][index].l + tree[pos][index].r) >> 1; if (mid >= r) modify(pos,index*2,l,r,val); else if (mid + 1 <= l) modify(pos,index*2+1,l,r,val); else { modify(pos,index*2,l,mid,val); modify(pos,index*2+1,mid+1,r,val); } pushup(pos,index); } } int main() { read(R); read(C); read(Q); for (i = 1; i <= R; i++) { for (j = 1; j <= C; j++) { ch = getchar(); mat[i][j] = ch - '0'; } getchar(); } for (i = 1; i <= C; i++) { for (j = 1; j <= R; j++) { sum[j][i] = sum[j-1][i] + mat[j][i]; } } for (i = 1; i <= C; i++) build(i,1,1,R); while (Q--) { ans = 0; read(R1); read(R2); read(C1); read(C2); read(X); for (i = C1; i <= C2; i++) modify(i,1,R1,R2,X); for (i = 1; i <= C; i++) ans += tree[i][1].sum; writeln(ans); } return 0; }