2018 牛客多校第二场 J farm

版权声明:欢迎转载,请注明出处噢,谢谢 https://blog.csdn.net/DT2131/article/details/81202296

题意:

翻译直接搬别人的了。

给出一个n*m(n*m<=1e6)的农场,以及每个格子中植物的种类编号∈[1,n*m],

接着给出T(T<=1e6)次施肥的信息,信息包括x1,y1,x2,y2,k(1<=x1<=x2<=n,1<=y1<=y2<=m,1<=k<=n*m)

表示给在坐标(x1,y1)到坐标(x2,y2)的区间中全部植物施加编号为k的肥料。

已知植物被不同于自身编号的肥料施加后会死去,问全部施肥操作后有多少株植物会死去。

原文链接: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.

思路:

考虑二维线段树/二维树状数组/或四分树

四分树思路:

四分树原理同线段树,在push down lazy标记时

若区间内被两种化肥同时撒到,则置lazy为-1代表区间内的花已全死,其他情况简单分析一下也很好写。

最后查询全部push down一边,统计即可。
代码:

#include <bits/stdc++.h>
const int MAXN=1e6+7;
using namespace std;
int tree[MAXN*20];
int son[MAXN*20][4];
int n,m,t;
int id;
vector<int>a[MAXN];
int stx,enx,sty,eny,v;
 
void push_down(int rt){
    if(tree[rt]==0){
        return;
    }else if(tree[rt]==-1){
        tree[son[rt][0]]=tree[son[rt][1]]=tree[son[rt][2]]=tree[son[rt][3]]=-1;
    }else{
        for(int i=0;i<4;i++){
            if(tree[son[rt][i]]==0) tree[son[rt][i]]=tree[rt];
            else if(tree[son[rt][i]]!=tree[rt]) tree[son[rt][i]]=-1;
            else continue;
        }
    }
}
void build(int lx,int rx,int ly,int ry,int rt){
    tree[rt]=0;
    if(lx==rx&&ly==ry){
 
        return ;
    }
    int midx=(lx+rx)/2;
    int midy=(ly+ry)/2;
    build(lx,midx,ly,midy,son[rt][0]=++id);
    if(ly!=ry) build(lx,midx,midy+1,ry,son[rt][1]=++id);
    if(lx!=rx) build(midx+1,rx,ly,midy,son[rt][2]=++id);
    if(ly!=ry&&lx!=rx) build(midx+1,rx,midy+1,ry,son[rt][3]=++id);
}
int query(int lx,int rx,int ly,int ry,int rt){
    if(tree[rt]==-1){
        return 0;
    }
 
    if(lx==rx&&ly==ry){
        if(tree[rt]==0||tree[rt]==a[lx][ly]){
            return 1;
        }
        return 0;
    }
    int midx=(lx+rx)/2;
    int midy=(ly+ry)/2;
    push_down(rt);
    int ans=0;
    ans+=query(lx,midx,ly,midy,son[rt][0]);
    if(ly!=ry) ans+=query(lx,midx,midy+1,ry,son[rt][1]);
    if(lx!=rx) ans+=query(midx+1,rx,ly,midy,son[rt][2]);
    if(ly!=ry&&lx!=rx) ans+=query(midx+1,rx,midy+1,ry,son[rt][3]);
    return ans;
}
void update(int lx,int rx,int ly,int ry,int rt){
    if(tree[rt]==-1||stx>rx||sty>ry||enx<lx||eny<ly) return ;
    if(stx<=lx&&rx<=enx&&sty<=ly&&ry<=eny){
        if(tree[rt]==0||tree[rt]==v){
            tree[rt]=v;
            return ;
        }else{
            tree[rt]=-1;
            return ;
        }
    }
    push_down(rt);
    int midx=(lx+rx)/2;
    int midy=(ly+ry)/2;
    update(lx,midx,ly,midy,son[rt][0]);
    if(ly!=ry) update(lx,midx,midy+1,ry,son[rt][1]);
    if(lx!=rx) update(midx+1,rx,ly,midy,son[rt][2]);
    if(ly!=ry&&lx!=rx) update(midx+1,rx,midy+1,ry,son[rt][3]);
    //push_up(rt);
}
int main()
{
 
    ios::sync_with_stdio(false);
    //freopen("in.txt","r",stdin);
 
    cin>>n>>m>>t;id=1;
    if(n==0||m==0){cout<<0<<endl;return 0;}
    for(int i=1;i<=n;i++){
        a[i].push_back(0);
        for(int j=1;j<=m;j++){int x;cin>>x;
            a[i].push_back(x);
        }
    }
 
    build(1,n,1,m,1);
    while(t--){cin>>stx>>sty>>enx>>eny>>v;
        update(1,n,1,m,1);
    }
    cout<<n*m-query(1,n,1,m,1)<<endl;
}

 

展开阅读全文

没有更多推荐了,返回首页