牛客多校第二场 J farm(二维树状数组)

链接: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 <bits/stdc++.h>
#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<<"["<<x<<"]"<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>pii;
const int MX=1e6+7;

int n,m,t;
vector<int>bit[MX];
vector<pii>point[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;
};
vector<que>q[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;
}

猜你喜欢

转载自blog.csdn.net/lee_w_j__/article/details/81149626
今日推荐