牛客网暑期ACM多校训练营(第二场)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

ps:二维差分,a[x1][y1]++,a[x1][y2+1]–,a[x2+1][y1]–,a[x2+1][y2+1]++

思路:这题做法挺多的,这里说两种
第一种:
如果这些数都是0或者一的话就很好写了,因为这里数的范围不是很大,所以我们就可以用二进制表示,考虑每一位的贡献就行,用两个二维数组对比下就行,这里的二维差分因为是一维数组表示二维数组,所以记录下板子吧
accode

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e6+43;
int n,m;
int T;
int map1[maxn];
int map2[maxn];
struct node
{
    int x1,x2;
    int y1,y2;
    int x;
}Q[maxn];
int ans[maxn];
int va[maxn];
void update1(int i)
{  ++map1[(Q[i].x1-1)*m+Q[i].y1];
    if (Q[i].x2<n) --map1[(Q[i].x2)*m+Q[i].y1];
    if (Q[i].y2<m) --map1[(Q[i].x1-1)*m+Q[i].y2+1];
    if (Q[i].x2<n&&Q[i].y2<m) ++map1[Q[i].x2*m+Q[i].y2+1];

}
void update2(int i)
{  ++map2[(Q[i].x1-1)*m+Q[i].y1];
    if (Q[i].x2<n) --map2[(Q[i].x2)*m+Q[i].y1];
    if (Q[i].y2<m) --map2[(Q[i].x1-1)*m+Q[i].y2+1];
    if (Q[i].x2<n&&Q[i].y2<m) ++map2[Q[i].x2*m+Q[i].y2+1];

}
void presum1()
{
    int i,j,t;
    for (i=t=1;i<=n;i++)
        for (j=1;j<=m;j++,t++) {
            if (i>1) map1[t]+=map1[t-m];
            if (j>1) map1[t]+=map1[t-1];
            if (i>1&&j>1) map1[t]-=map1[t-m-1];
        }
}
void presum2()
{
    int i,j,t;
    for (i=t=1;i<=n;i++)
        for (j=1;j<=m;j++,t++) {
            if (i>1) map2[t]+=map2[t-m];
            if (j>1) map2[t]+=map2[t-1];
            if (i>1&&j>1) map2[t]-=map2[t-m-1];
        }
}
int main()
{
    scanf("%d%d%d",&n,&m,&T);
    for(int i = 1;i<=n;i++){
        for(int j = 1;j<=m;j++){
            int x;
            scanf("%d",&x);
            va[(i-1)*m+j] =  x;
        }
    }
    for(int i = 0;i<T;i++){
        scanf("%d%d%d%d%d",&Q[i].x1,&Q[i].y1,&Q[i].x2,&Q[i].y2,&Q[i].x);
        update1(i);
    }
    presum1();
    for(int bit = 0;bit<20;bit++){
        for(int i = 1;i<=n*m;i++){
            map2[i] = 0;
        }
        for(int i = 0;i<T;i++){
            if(Q[i].x&(1<<bit)){
                update2(i);
            }
        }
        presum2();
        for(int i = 1;i<=n*m;i++){
            if(va[i]&(1<<bit)){
                if(map1[i]!=map2[i]){
                    ans[i] = 1;
                }
            }
            else{
                if(map2[i]){
                    ans[i] = 1;
                }
            }
        }
    }
    int sum = 0;
    for(int i =1;i<=n;i++){
        for(int j = 1;j<=m;j++){
            if(ans[(i-1)*m+j]==1){
                sum++;
            }
        }
    }
    cout<<sum<<endl;
}

第二种:
待补:

猜你喜欢

转载自blog.csdn.net/w571523631/article/details/81188938