P2930 [USACO09HOL]假期绘画Holiday Painting

时间:2023-09-18 17:05:08

线段树水题,考虑到只有15列,所以我们对于每一列,我们都去维护一个线段树。

现在来考虑一下修改操作,因为每次修改的时候,我们都是将黑的改成白的,白的改成黑的,所以我们对线段树的每个节点维护当前这段区间和原来颜色相同的点的个数,所以每次改成白色我们只需要找原来是白色的总数,或者黑色,所以就特别简单了。

下面是代码。

//author Eterna
#define Hello the_cruel_world!
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<utility>
#include<cmath>
#include<climits>
#include<deque>
#include<functional>
#include<complex>
#include<numeric>
#include<unordered_map>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define Pi acos(-1.0)
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
#define pb(x) push_back(x)
#define lowbit(x) (x & -x)
#define FRIN freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\in.txt", "r", stdin)
#define FROUT freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\out.txt", "w", stdout)
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define outd(x) printf("%d\n", x)
#define outld(x) printf("%lld\n", x)
#define il inline
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int maxn = 5e4;
const int INF = 0x7fffffff;
const int mod = 1e9 + 7;
const double eps = 1e-7;
inline int read_int() {
char c;
int ret = 0, sgn = 1;
do { c = getchar(); } while ((c < '0' || c > '9') && c != '-');
if (c == '-') sgn = -1; else ret = c - '0';
while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0');
return sgn * ret;
}
inline ll read_ll() {
char c;
ll ret = 0, sgn = 1;
do { c = getchar(); } while ((c < '0' || c > '9') && c != '-');
if (c == '-') sgn = -1; else ret = c - '0';
while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0');
return sgn * ret;
}
int white[16][maxn + 5], black[16][maxn + 5];
int arr[16][4 * maxn + 5], lazy[16][4 * maxn + 5];
char s[20];
il void Push_Up(int id, int index) {
arr[id][index] = arr[id][2 * index] + arr[id][2 * index + 1];
}
il void Change(int id, int index, int L, int R, int color) {
if (color) {
int sum = black[id][R] - black[id][L - 1];
arr[id][index] = sum;
}
else {
int sum = white[id][R] - white[id][L - 1];
arr[id][index] = sum;
}
}
il void Push_Down(int id, int index, int L, int R) {
int mid = L + R >> 1;
Change(id, 2 * index, L, mid, lazy[id][index]);
Change(id, 2 * index + 1, mid + 1, R, lazy[id][index]);
lazy[id][2 * index] = lazy[id][2 * index + 1] = lazy[id][index];
lazy[id][index] = -1;
}
void Build(int id, int index, int L, int R) {
lazy[id][index] = -1;
if (L == R) {
arr[id][index] = white[id][L];
return;
}
int mid = L + R >> 1;
Build(id, 2 * index, L, mid);
Build(id, 2 * index + 1, mid + 1, R);
Push_Up(id, index);
}
void Update(int id, int index, int L, int R, int UL, int UR, int c) {
if (L >= UL && R <= UR) {
Change(id, index, L, R, c);
lazy[id][index] = c;
return;
}
if (lazy[id][index] != -1)Push_Down(id, index, L, R);
int mid = L + R >> 1;
if (mid >= UL)Update(id, 2 * index, L, mid, UL, UR, c);
if (UR > mid) Update(id, 2 * index + 1, mid + 1, R, UL, UR, c);
Push_Up(id, index);
}
il int Query(int m) {
int res = 0;
for (int i = 1; i <= m; ++i)res += arr[i][1];
return res;
}
int n, m, r1, r2, c1, c2, q, c, cnt;
int main()
{
n = read_int(), m = read_int(), q = read_int();
for (int i = 1; i <= n; ++i) {
scanf("%s", s + 1);
for (int j = 1; j <= m; ++j) {
if (s[j] == '1') black[j][i] = 1;
else white[j][i] = 1, ++cnt;
}
}
for (int i = 1; i <= m; ++i)Build(i, 1, 1, n);
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j) {
white[i][j] += white[i][j - 1];
black[i][j] += black[i][j - 1];
}
while (q--) {
r1 = read_int(), r2 = read_int(), c1 = read_int(), c2 = read_int(), c = read_int();
for (int i = c1; i <= c2; ++i)Update(i, 1, 1, n, r1, r2, c);
outd(Query(m));
}
//system("pause");
return 0;
}