一开始没注意数据范围~
可以发现列最大只有15。
并且我们修改的是一个矩形。
那么就是一列列修改并且统计答案。
这里就可以用线段树,对每列建树,然后更新统计答案。
具体怎么统计,就是因为每次都是将一个区间内的数改成1或0,那么我们先统计出每个区间的标准1和0个数。
那么改成哪个就是哪个为相同的答案。
然后注意一些细节就行了
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 5e4+5; const int M = 1e6+5; const LL Mod = 1e9+7; #define rg register #define pi acos(-1) #define INF 1e9 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; void FRE(){/*freopen("data1.in","r",stdin); freopen("data1.out","w",stdout);*/} int n,m,q; string a[N]; struct Node{int L,r,sum1,sum0,val,tag;}node[20][N<<2]; void Pushup(int id,int idx) { node[id][idx].val = node[id][idx<<1].val + node[id][idx<<1|1].val; } void Pushdown(int id,int idx) { if(node[id][idx].tag != -1) { int tag = node[id][idx].tag; if(tag == 0) { node[id][idx<<1].val = node[id][idx<<1].sum0; node[id][idx<<1|1].val = node[id][idx<<1|1].sum0; } else { node[id][idx<<1].val = node[id][idx<<1].sum1; node[id][idx<<1|1].val = node[id][idx<<1|1].sum1; } node[id][idx<<1].tag = node[id][idx<<1|1].tag = tag; node[id][idx].tag = -1; } } void build(int L,int r,int id,int idx) { node[id][idx].L = L,node[id][idx].r = r; node[id][idx].tag = -1; if(L == r) { if(a[L-1][id-1] == '0') node[id][idx].sum0++,node[id][idx].val = 1; else node[id][idx].sum1++; return ; } int mid = (L+r)>>1; build(L,mid,id,idx<<1); build(mid+1,r,id,idx<<1|1); node[id][idx].sum0 = node[id][idx<<1].sum0 + node[id][idx<<1|1].sum0;//上限 node[id][idx].sum1 = node[id][idx<<1].sum1 + node[id][idx<<1|1].sum1; Pushup(id,idx); } void update(int L,int r,int id,int idx,int val) { if(node[id][idx].L >= L && node[id][idx].r <= r) { if(val == 0) node[id][idx].val = node[id][idx].sum0; else node[id][idx].val = node[id][idx].sum1; node[id][idx].tag = val; return ; } int mid = (node[id][idx].L + node[id][idx].r)>>1; Pushdown(id,idx); if(mid >= L) update(L,r,id,idx<<1,val); if(mid < r) update(L,r,id,idx<<1|1,val); Pushup(id,idx); } int main() { IO;CT0; cin >> n >> m >> q; for(rg int i = 0;i < n;++i) cin >> a[i]; for(rg int j = 0;j < m;++j) build(1,n,j+1,1); while(q--) { int r1,r2,c1,c2,z; cin >> r1 >> r2 >> c1 >> c2 >> z; for(rg int i = c1;i <= c2;++i) update(r1,r2,i,1,z); int ans = 0; for(rg int i = 1;i <= m;++i) ans += node[i][1].val; cout << ans << endl; } system("pause"); }View Code