White Rabbit has a rectangular farmland of n*m. In each of the grid there is a kind of plant. The plant in the j-th column of the i-th row belongs the a[i][j]-th type.
White Cloud wants to help White Rabbit fertilize plants, but the i-th plant can only adapt to the i-th fertilizer. If the j-th fertilizer is applied to the i-th plant (i!=j), the plant will immediately die.
Now White Cloud plans to apply fertilizers T times. In the i-th plan, White Cloud will use k[i]-th fertilizer to fertilize all the plants in a rectangle [x1[i]...x2[i]][y1[i]...y2[i]].
White rabbits wants to know how many plants would eventually die if they were to be fertilized according to the expected schedule of White Cloud.
The first line of input contains 3 integers n,m,T(n*m<=1000000,T<=1000000) For the next n lines, each line contains m integers in range[1,n*m] denoting the type of plant in each grid. For the next T lines, the i-th line contains 5 integers x1,y1,x2,y2,k(1<=x1<=x2<=n,1<=y1<=y2<=m,1<=k<=n*m)
Print an integer, denoting the number of plants which would die.
示例1
2 2 2 1 2 2 3 1 1 2 2 2 2 1 2 1 1
3
将每一个农田上的数字看成2进制,如果多次施肥中同一块农田上施肥的种类不同,那么这些数字必有一位二进制数不同。
先统计每一块农田被使了多少次肥。即统计每一块农田,二进制的每一位有多少个0和1。
然后按位遍历,若0,1同时出现,则植物死亡。
#include
#define maxn 1000010
using namespace std;
int a[maxn],x1[maxn],x2[maxn],y2[maxn],num[maxn],S[maxn],T[maxn],ans[maxn];
int y_1[maxn];
int n,m,t;
int id(int x,int y)
{
return (x-1)*m+y;
}
void add(int i,int *s)//add和work统计施肥次数
{
s[id(x1[i],y_1[i])]++;
if(y2[i]+1<=m) s[id(x1[i],y2[i])+1]--;
if(x2[i]+1<=n) s[id(x2[i]+1,y_1[i])]--;
if(x2[i]+1<=n&&y2[i]+1<=m)
s[id(x2[i]+1,y2[i]+1)]++;
}
void work(int *s)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j>1) s[id(i,j)]+=s[id(i,j-1)];
if(i>1) s[id(i,j)]+=s[id(i-1,j)];
if(i>1&&j>1) s[id(i,j)]-=s[id(i-1,j-1)];
}
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&t)!=EOF)
{
memset(ans,0,sizeof(ans));
for(int i=1;i<=n*m;i++)
scanf("%d",&a[i]);
for(int i=1;i<=t;i++)
{
scanf("%d%d%d%d%d",&x1[i],&y_1[i],&x2[i],&y2[i],&num[i]);
add(i,S);
}
work(S);
for(int u=0;u<20;u++)//按位遍历
{
memset(T,0,sizeof(T));
for(int i=1;i<=t;i++)
{
if((num[i]>>u)&1)//只统计1出现的次数
add(i,T);
}
work(T);
for(int i=1;i<=n*m;i++)
{
bool flag;
if((a[i]>>u)&1)//若植物在这一位上的数是1
flag=true;
else
flag=false;
if(flag)//这一位是1的情况
{
if(S[i]>T[i])//如果总数比1的个数多说明有0,则植物死
ans[i]=1;
}
else//这一位是0的情况
{
if(T[i])//若出现1,则植物死
ans[i]=1;
}
}
}
int k=0;
for(int i=1;i<=n*m;i++)
{
if(ans[i])
k++;
}
printf("%d\n",k);
}
return 0;
}