牛客网多校训练2 J farm(rand+二维树状数组)

题意:就是花园里有一些花,这些花都有一个编号,他的编号就是他说需要的肥料,一朵花施其他的肥料就会死,有很多操作,每次都是将一个正方形撒化肥,最后问你死了几朵花

思路:这个题在听直播讲题的时候说时候三种解法,一种是用树状数组,一种是扫描线,一种就是rand,rand 的思路其实就是给每种化肥随机一个权值,如果其他的肥料撒到了,他们同余之后是有余数的,所以就代表死了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
#include <vector>
#include <stack>
using namespace std;
typedef long long LL;
const int maxn=1e6+7;
LL lowbit(int x){return x&(-x);}
vector<LL>ans[maxn];
vector<LL>g[maxn];
LL Hash[maxn];
int n,m,t;
const int MOD=1e9+7;
void init()
{
    for(int i=1;i<=1e6;i++){
        Hash[i]=rand()*MOD/7;
    }
}
 
void update(int x,int y,int val)
{
    for(int i=x;i<=n;i+=lowbit(i)){
        for(int j=y;j<=m;j+=lowbit(j)){
            ans[i][j]+=val;
        }
    }
}
bool check(int x,int y)
{
    LL res=0;
    for(int i=x;i>=1;i-=lowbit(i)){
        for(int j=y;j>=1;j-=lowbit(j)){
            res+=ans[i][j];
        }
    }
    if(res%g[x][y])return true;
    return false;
}
int main()
{
    init();
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=n;i++){
        g[i].push_back(0);
        ans[i].push_back(0);
        for(int j=1;j<=m;j++){
            int x;
            scanf("%d",&x);
            g[i].push_back(Hash[x]);
            ans[i].push_back(0);
        }
    }
    for(int i=1;i<=t;i++){
        int x1,x2,y1,y2,k;
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&k);
        update(x1,y1,Hash[k]);
        update(x2+1,y2+1,Hash[k]);
        update(x2+1,y1,-Hash[k]);
        update(x1,y2+1,-Hash[k]);
    }
    int sum=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(check(i,j))sum++;
        }
    }
    printf("%d
",sum);
    return 0;
}
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9362385.html