题目链接:点击这里
解题思路:只要田上被施上一次不同的肥料那么植物就死了。那么我们知道两个值不同那么他们的二进制位至少有一位是不同的。
根据这一特点,先可以用前缀和求出一块田被施了几次肥。然后枚举每个二进制位,将原来的施肥操作变为施肥值的该二进制位是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;
}