ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

农夫小Q将他的奶牛们饲养在一个长n宽m的矩形网格牧场中。行从上到下依次编号为1到n,列从左往右依次编号为1
到m。为了防止奶牛们逃跑,小Q在牧场外圈安装了一排电网,只要奶牛走出这个n*m的矩形,就会触电死去。在牧
场中,有e个格子塌陷了,一旦奶牛踩在上面,就会掉下去摔死。小Q为了饲养尽可能多的奶牛,在每个没有塌陷的
格子上,都饲养着一头奶牛。tangjz偷走了小Q的口哨,并用口哨向奶牛们依次施放了q条指令,每条指令包含两个
参数d和k,d表示上下左右之一的方向,k表示前进步数。发出指令后,每头奶牛都会听话地执行指令,甚至会因此
丧生。所有奶牛移动完毕之后,tangjz才会施放下一条指令。请写一个程序统计每条指令中小Q损失了多少头奶牛

Input

第一行包含4个正整数n,m,e,q(1<=n,m,q<=2000,0<=e<=min(nm,2000))
分别表示牧场的长宽、塌陷的格子数以及指令数。
接下来e行,每行两个正整数x_i,y_i(1<=x_i<=n,1<=y_i<=m)
表示每个塌陷格子的坐标。输入数据保证每个格子不会被描述多次。
接下来q行,每行包含一个字符d和一个正整数k(1<=k<=2000)
描述每条指令。其中UDLR分别表示上下左右。

Output

输出q行,每行一个整数,即第i条指令中损失的奶牛数量。

塌陷的格子数和询问数都很少,可以反过来移动这些格子来计算每次新覆盖了多少位置,查询区间内未被覆盖的位置可以用zkw线段树实现,时间复杂度O(qelog(n+m)+nm)。

#include<bits/stdc++.h>
const int N=2055;
int n,m,e,q,mx;
int xs[N],ys[N],dc=0,tr[2][N][N*2],ds[N*N],dp=0,*t,Q[N];
bool dd[N][N];
void del(int x,int y){
    if(!dd[x][y])dd[x][y]=1,++dc;
}
void chk(int*t,int x){
    for(int w=x;w>1&&!t[w^1];t[w>>=1]=0);
    int ql=0,qr=0;
    t[x]=0,Q[++qr]=x;
    while(ql!=qr){
        int w=Q[++ql];
        if(w>=mx)ds[dp++]=w-mx;
        else{
            w<<=1;
            if(t[w])t[w]=0,Q[++qr]=w;
            ++w;
            if(t[w])t[w]=0,Q[++qr]=w;
        }
    }
}
void dt(int*t,int l,int r){
    for(l+=mx-1,r+=mx+1;r-l!=1;l>>=1,r>>=1){
        if(~l&1&&t[l+1])chk(t,l+1);
        if(r&1&&t[r-1])chk(t,r-1);
    }
}
void dlr(int x,int l,int r){
    if(x<1||x>n)return;
    if(r>m)r=m;if(l<1)l=1;
    if(l<=r)dt(tr[0][x],l,r);
    for(;dp;del(x,ds[--dp]));
}
void dud(int y,int l,int r){
    if(y<1||y>m)return;
    if(r>n)r=n;if(l<1)l=1;
    if(l<=r)dt(tr[1][y],l,r);
    for(;dp;del(ds[--dp],y));
}
void init(int*t,int c){
    for(int i=1;i<=c;++i)t[mx+i]=1;
    for(int i=mx-1;i;--i)t[i]=t[i<<1]|t[(i<<1)+1];
}
int main(){
    scanf("%d%d%d%d",&n,&m,&e,&q);
    for(mx=1;mx<=std::max(n,m)+5;mx<<=1);
    for(int i=1;i<=e;++i)scanf("%d%d",xs+i,ys+i),del(xs[i],ys[i]);
    for(int i=1;i<=n;++i)init(tr[0][i],m);
    for(int i=1;i<=m;++i)init(tr[1][i],n);
    int lp=0,rp=m+1,up=0,dp=n+1;
    while(q--){
        char dir;
        int d,v0=dc;
        scanf(" %c%d",&dir,&d);
        if(dir=='R'){//m-
            for(int i=1;i<=e;++i)dlr(xs[i],ys[i]-d,ys[i]),ys[i]-=d;
            for(int i=1;i<=n;++i)dlr(i,rp-d,rp);
            lp-=d,rp-=d;
        }
        if(dir=='L'){//m+
            for(int i=1;i<=e;++i)dlr(xs[i],ys[i],ys[i]+d),ys[i]+=d;
            for(int i=1;i<=n;++i)dlr(i,lp,lp+d);
            lp+=d,rp+=d;
        }
        if(dir=='D'){//n-
            for(int i=1;i<=e;++i)dud(ys[i],xs[i]-d,xs[i]),xs[i]-=d;
            for(int i=1;i<=m;++i)dud(i,dp-d,dp);
            up-=d,dp-=d;
        }
        if(dir=='U'){//n+
            for(int i=1;i<=e;++i)dud(ys[i],xs[i],xs[i]+d),xs[i]+=d;
            for(int i=1;i<=m;++i)dud(i,up,up+d);
            up+=d,dp+=d;
        }
        printf("%d\n",dc-v0);
    }
    return 0;
}

 

posted on 2017-10-19 10:30  nul  阅读(271)  评论(0编辑  收藏  举报