题目链接:点击这里

 

解题思路:只要田上被施上一次不同的肥料那么植物就死了。那么我们知道两个值不同那么他们的二进制位至少有一位是不同的。

根据这一特点,先可以用前缀和求出一块田被施了几次肥。然后枚举每个二进制位,将原来的施肥操作变为施肥值的该二进制位是1才施肥,那么如果一块田两次施肥次数不等,说明该块田至少被一个不等于田地值的肥料施过,那么他肯定就废了。

 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<set>
#define inf 0x3f3f3f3f
#define gi(i) scanf("%d",&i)
using namespace std;
const int N = 1e6 + 10;
typedef long long ll;
int a[N],s[N],f[N];
#define y1 y_1
int x1[N],y1[N],x2[N],y2[N],tp[N];
int n,m;
bool die[N];
#define id(x,y) (((x)-1)*m+(y))
void add(int k,int *f) {
	++f[id(x1[k],y1[k])];
	if (x2[k]<n) --f[id(x2[k]+1,y1[k])];
	if (y2[k]<m) --f[id(x1[k],y2[k]+1)];
	if (x2[k]<n&&y2[k]<m) ++f[id(x2[k]+1,y2[k]+1)];
}
void work(int *s) {
	int i,j,t;
	for (i=t=1;i<=n;i++)
		for (j=1;j<=m;j++,t++) {
			if (i>1) s[t]+=s[t-m];
			if (j>1) s[t]+=s[t-1];
			if (i>1&&j>1) s[t]-=s[t-m-1];
		}
}
int main()
{
	int i,v,T;
	gi(n),gi(m),gi(T);
	for (i=1;i<=n*m;i++)
		gi(a[i]);
	for (i=1;i<=T;i++) {
		gi(x1[i]),gi(y1[i]),gi(x2[i]),gi(y2[i]),gi(tp[i]);
		add(i,s);
	}
	work(s);
	for (v=0;v<20;v++) {
		for (i=1;i<=n*m;i++) f[i]=0;
		for (i=1;i<=T;i++)
			if (tp[i]>>v&1) {
				add(i,f);
			}
		work(f);
		for (i=1;i<=n*m;i++)
			if (a[i]>>v&1) {
				if (f[i]!=s[i]) {
					die[i]=true;
				}
			} else {
				if (f[i]) {
					die[i]=true;
				}
			}
	}
	v=0;
	for (i=1;i<=n*m;i++) {
		v+=die[i];
	}
	printf("%d\n",v);
	return 0;
}