一道神奇的并查集

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
template<class T> inline void read(T &_a){
    bool f=0;int _ch=getchar();_a=0;
    while(_ch<'0' || _ch>'9'){if(_ch=='-')f=1;_ch=getchar();}
    while(_ch>='0' && _ch<='9'){_a=(_a<<1)+(_a<<3)+_ch-'0';_ch=getchar();}
    if(f)_a=-_a;
}

struct fff{int x,y;}node[100001];
int n,m,q,e,mp[4][2010][2010],res;
bool del[2010][2010];

inline void erase(int x,int y)
{
    if(del[x][y]) return ;
    del[x][y]=true;
    ++res;
    --mp[0][x][y];
    ++mp[1][x][y];
    --mp[2][x][y];
    ++mp[3][x][y];
}

inline int findx(int o,int x,int y)
{
    return mp[o][x][y]==x?x:mp[o][x][y]=findx(o,mp[o][x][y],y);
}

inline int findy(int o,int x,int y)
{
    return mp[o][x][y]==y?y:mp[o][x][y]=findy(o,x,mp[o][x][y]);
}

inline void up(int k)
{
    for (register int i=1;i<=e;++i)
    {
        int x=min(node[i].x,n),y=node[i].y;
        node[i].x-=k;
        if(y<1||y>m) continue;
        if(x<1) continue;
        while(x>0&&x>=node[i].x)
        {
            x=findx(0,x,y);
            if(x>0&&x>=node[i].x) erase(x,y);
        }
    }
}

inline void down(int k)
{
    for (register int i=1;i<=e;++i)
    {
        int x=max(node[i].x,1),y=node[i].y;
        node[i].x+=k;
        if(y<1||y>m) continue;
        if(x>n) continue;
        while(x>0&&x<=node[i].x&&x<=n)
        {
            x=findx(1,x,y);
            if(x>0&&x<=node[i].x&&x<=n) erase(x,y);
        }
    }
}

inline void left(int k)
{
    for (register int i=1;i<=e;++i)
    {
        int y=min(node[i].y,m),x=node[i].x;
        node[i].y-=k;
        if(x<1||x>n) continue;
        if(y<1) continue;
        while(y>0&&y>=node[i].y)
        {
            y=findy(2,x,y);
            if((y>0&&y>=node[i].y)) erase(x,y);
        }
    }
}

inline void right(int k)
{
    for (register int i=1;i<=e;++i)
    {
        int y=max(node[i].y,1),x=node[i].x;
        node[i].y+=k;
        if(x<1||x>n) continue;
        if(y>m) continue;
        while(y>0&&y<=node[i].y&&y<=m)
        {
            y=findy(3,x,y);
            if(y>0&&y<=node[i].y&&y<=m) erase(x,y);
        }
    }
}

int main()
{
    read(n); read(m); read(e); read(q);
    for (register int i=1;i<=n;++i)
        for (register int v=1;v<=m;++v)
            mp[0][i][v]=mp[1][i][v]=i,mp[2][i][v]=mp[3][i][v]=v;
    for (register int i=1;i<=e;++i) read(node[i].x),read(node[i].y);
    for (register int i=1;i<=e;++i) erase(node[i].x,node[i].y);
    for (register int i=1;i<=n;++i) node[++e].x=i,node[e].y=0,node[++e].x=i,node[e].y=m+1;
    for (register int i=1;i<=m;++i) node[++e].x=0,node[e].y=i,node[++e].x=n+1,node[e].y=i;
    while(q--)
    {
        register char op=getchar();
        while(op!='R'&&op!='L'&&op!='D'&&op!='U') op=getchar();
        register int k; read(k);
        res=0;
        if(op=='R') left(k);
        else if (op=='L') right(k);
        else if (op=='D') up(k);
        else down(k);
        printf("%d\n",res);
    }
    return 0;
}

 

posted @ 2017-11-02 19:41  JayWang  阅读(159)  评论(0编辑  收藏  举报