链接:https://www.nowcoder.com/acm/contest/140/J
来源:牛客网
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
题目大意:有一块大小为n*m的农田,每一个地上都种着种类为a[i][j]的植物,接下来要进行T次农药喷洒,每次会对左上角为(x1,y1),右下角为(x2,y2)的矩阵喷洒类型为k的农药,如果被喷洒的植物的种类和农药的种类不同(也就是a[i][j]!=k),这个植物就会死掉。问在T次喷洒之后这n*m个植物有多少个死掉了。
题目思路:一个植物死掉的条件是这个植物被喷洒了与它种类不同的农药,那么我们就可以在喷洒的时候先把所有的农药都按范围喷洒上去(对于矩阵内的值加1),然后对于第 i 种植物,我们再将第 i 种农药喷洒效果去除,再查询这个植物是否被其它农药喷洒过(也就是是否大于0),然后再将去除的效果加回去即可,由于植物的种类最多是n*m=1e6种,所以我们可以考虑用vector来存储不同种类植物的坐标和农药的覆盖范围。而矩阵覆盖和删除的操作我们可以借助二维树状数组来完成,时间复杂度大概是(nm+T)log(nm)log(nm)。(大佬们都是用一个log的做法,还得再学习学习,orz...)
具体实现看代码:
#include
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pb push_back
#define MP make_pair
#define lowbit(x) x&-x
#define FIN freopen("in.txt","r",stdin)
#define fuck(x) cout<<"["<pii;
const int MX=1e6+7;
int n,m,t;
vectorbit[MX];
vectorpoint[MX];
inline void add(int x,int y,int z){
for(int i=x;i<=n;i+=lowbit(i)){
for(int j=y;j<=m;j+=lowbit(j))
bit[i][j]+=z;
}
}
inline void update(int x1,int Y1,int x2,int y2,int z){
add(x1,Y1,z);add(x2+1,y2+1,z);
add(x1,y2+1,-z);add(x2+1,Y1,-z);
}
inline int query(int x,int y){
int res=0;
for(int i=x;i;i-=lowbit(i)){
for(int j=y;j;j-=lowbit(j))
res+=bit[i][j];
}
return res;
}
struct que{
int a,b,c,d;
};
vectorq[MX];
int main(){
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++) bit[i].resize(m+1);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int z;
scanf("%d",&z);
point[z].pb(MP(i,j));
}
}
for(int i=1;i<=t;i++){
int a,b,c,d,k;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
update(a,b,c,d,1);
q[k].pb(que{a,b,c,d});
}
int ans=0;
for(int i=1;i<=n*m;i++){
if(point[i].size()){
for(auto nw:q[i])
update(nw.a,nw.b,nw.c,nw.d,-1);
for(auto nw:point[i]){
if(query(nw.fi,nw.se)) ans++;
}
for(auto nw:q[i])
update(nw.a,nw.b,nw.c,nw.d,1);
}
}
printf("%d\n",ans);
return 0;
}