Description
从前有一个Baby。
从前还有一个网格图。
Baby 喜欢爆炸。
Baby 偶尔会炸掉网格图中的一条边(u, v)。之后他会尝试从u 走到v。
如果他成功地从u 走到v,他会很高兴;否则他会找人打架。
从第二次爆炸开始,根据Baby 此时心情的不同,Baby 会炸掉不同的边。
你被要求编写一个程序,对于每次爆炸,给出此时Baby 是否还能从u 到v。
Solution
这题因为有要用到上一轮的答案,所以离线几乎不可做,想想在线怎么做,
试着把删掉的边做并查集,
发现,如果两条边有公共点,并且拐角为90度的两条边可以放在一个集合内,(读者自己用excel表格画画即可发现),
如果当前的线是横着的,那么判断一下其中一个端点的上下两条边是不是在一个集合中,
如果当前的线是竖着的,那么判断一下其中一个端点的左右两条边是不是在一个集合中,
复杂度: O(m)
Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int N=800;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,ans;
int a[N];
bool z[N][N][2];
int g[N*N*2+N];
int fx1[6][3]={{-1,0,1},{-1,1,1},{-1,0,0},{0,0,1},{0,1,1},{1,0,0}};
int fx2[6][3]={{0,0,1},{1,0,1},{0,1,0},{0,-1,1},{0,-1,0},{1,-1,1}};
void H(int &q,int &w,int &e,int x,int y,int x1,int y1)
{
if(x1<x||y1<y)swap(x,x1),swap(y,y1);
e=(x!=x1);q=x,w=y;
}
int H(int q,int w,int e)
{
if(!q||!w||(e&&(w>n||q>=n))||(!e&&(q>n||w>=n)))return 0;
return (q*n-n+w)*2-1+e;
}
int gf(int q)
{
return g[q]=(g[q]!=q?gf(g[q]):q);
}
int main()
{
int q,w,e,x,y,x1,y1,_;
read(n),read(_);_--;
fo(i,0,n*n*2+n)g[i]=i;
fo(i,0,n+1)z[i][0][0]=z[i][0][1]=z[0][i][0]=z[0][i][1]=
z[i][n][0]=z[n][i][1]=z[n+1][i][0]=z[n+1][i][1]=z[i][n+1][0]=z[i][n+1][1]=1;
read(x),read(y),read(x1),read(y1);H(q,w,e,x,y,x1,y1);
fo(i,0,5)if(z[q+fx2[i][0]][w+fx2[i][1]][e^fx2[i][2]])
g[gf(H(q+fx2[i][0],w+fx2[i][1],e^fx2[i][2]))]=H(q,w,e);
z[q][w][e]=1;printf("HAHA\n");ans=1;
while(_--)
{
if(!ans)fo(i,1,4)read(q);
read(x),read(y),read(x1),read(y1);
H(q,w,e,x,y,x1,y1);
if(ans)fo(i,1,4)read(x);
// if(z[q][w][e]){ans=0;printf("DAJIA\n");continue;}
ans=1;
if(!e)
{
int t=-1,t1=-1;
fo(i,0,2)if(z[q+fx1[i][0]][w+fx1[i][1]][e^fx1[i][2]])
t=gf(g[H(q+fx1[i][0],w+fx1[i][1],e^fx1[i][2])]);
fo(i,3,5)if(z[q+fx1[i][0]][w+fx1[i][1]][e^fx1[i][2]])
t1=gf(g[H(q+fx1[i][0],w+fx1[i][1],e^fx1[i][2])]);
if(t==t1&&t1!=-1)ans=0;
gf(H(q,w,e));
fo(i,0,5)
if(z[q+fx1[i][0]][w+fx1[i][1]][e^fx1[i][2]])
g[gf(H(q+fx1[i][0],w+fx1[i][1],e^fx1[i][2]))]=gf(H(q,w,e));
}else
{
int t=-1,t1=-1;
fo(i,0,2)if(z[q+fx2[i][0]][w+fx2[i][1]][e^fx2[i][2]])
t=gf(g[H(q+fx2[i][0],w+fx2[i][1],e^fx2[i][2])]);
fo(i,3,5)if(z[q+fx2[i][0]][w+fx2[i][1]][e^fx2[i][2]])
t1=gf(g[H(q+fx2[i][0],w+fx2[i][1],e^fx2[i][2])]);
if(t==t1&&t1!=-1)ans=0;
fo(i,0,5)if(z[q+fx2[i][0]][w+fx2[i][1]][e^fx2[i][2]])
g[gf(H(q+fx2[i][0],w+fx2[i][1],e^fx2[i][2]))]=gf(H(q,w,e));
}
z[q][w][e]=1;
if(ans)printf("HAHA\n");else printf("DAJIA\n");
}
return 0;
}