一道神奇的并查集
Posted JayWang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道神奇的并查集相关的知识,希望对你有一定的参考价值。
#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; }
以上是关于一道神奇的并查集的主要内容,如果未能解决你的问题,请参考以下文章