真是道神题,想写了一个月终于今天晚上把它解决了。想一下也真心不容易。我们用线段树维护这样几个量。
(懒得画了,原谅我盗图。。。)
我们用线段树维护这六个量,然后用一个数组a[x][0][0]表示第1行x位置与x+1位置的连通性,a[x][1][0]表示第二行x位置和x+1位置的连通性,a[x][0][1]表示第一行x位置与第二行x位置的连通性。线段树的合并和查询写的比较巧妙,具体细节可以参见代码。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 100010
using namespace std;
struct yts
{
bool s[2],x[2],v[2];
};
struct yts1
{
yts a;
int l,r;
}t[4*maxn];
bool a[maxn][2][2];
char s[10];
int T,n,r1,r2,c1,c2;
int dx[3]={-1,0,1};
int dy[3]={0,1,0};
void print(yts a)
{
printf("x:%d %d\ns:%d %d\nv:%d %d\n",a.x[0],a.x[1],a.s[0],a.s[1],a.v[0],a.v[1]);
}
void build(int i,int l,int r)
{
t[i].l=l;t[i].r=r;
if (l==r) {t[i].a.x[0]=t[i].a.x[1]=1;return;}
int mid=(l+r)>>1;
build(i<<1,l,mid);build(i<<1|1,mid+1,r);
}
void updata(yts &u,yts l,yts r,int mid)
{
u.s[0]= l.s[0] || (l.x[0]&&a[mid][0][0]&&a[mid][1][0]&&r.s[0]&&l.x[1]);//左上左下
u.s[1]= r.s[1] || (r.x[0]&&a[mid][0][0]&&a[mid][1][0]&&l.s[1]&&r.x[1]);//右上右下
u.x[0]= (l.x[0]&&a[mid][0][0]&&r.x[0]) || (l.v[0]&&a[mid][1][0]&&r.v[1]);//左上右上
u.x[1]= (l.x[1]&&a[mid][1][0]&&r.x[1]) || (l.v[1]&&a[mid][0][0]&&r.v[0]);//左下右下
u.v[0]= (l.v[0]&&a[mid][1][0]&&r.x[1]) || (l.x[0]&&a[mid][0][0]&&r.v[0]);//左上右下
u.v[1]= (l.v[1]&&a[mid][0][0]&&r.x[0]) || (l.x[1]&&a[mid][1][0]&&r.v[1]);//左下右上
}
void modify(int i,int x)
{
if (t[i].l==t[i].r)
{
t[i].a.s[0]=t[i].a.s[1]=t[i].a.v[0]=t[i].a.v[1]=a[x][0][1];
t[i].a.x[0]=t[i].a.x[1]=1;
return;
}
int mid=(t[i].l+t[i].r)>>1;
if (x<=mid) modify(i<<1,x);
else modify(i<<1|1,x);
updata(t[i].a,t[i<<1].a,t[i<<1|1].a,(t[i].l+t[i].r)>>1);
}
void change(bool f)
{
if (r1>r2) swap(r1,r2),swap(c1,c2);
int dir;
for (int i=0;i<3;i++)
if (c1+dx[i]==c2 && r1+dy[i]==r2) dir=i;
if (dir==0) a[c2][r2][0]=f,modify(1,c2);
else if (dir==1) a[c2][0][1]=f,modify(1,c2);
else a[c1][r1][0]=f,modify(1,c1);
}
yts query(int i,int l,int r)
{
if (l<=t[i].l && t[i].r<=r) return t[i].a;
int mid=(t[i].l+t[i].r)>>1;
if (r<=mid) return query(i<<1,l,r);
if (l>mid) return query(i<<1|1,l,r);
yts a=query(i<<1,l,r),b=query(i<<1|1,l,r),ans;
updata(ans,a,b,(t[i].l+t[i].r)>>1);
return ans;
}
void getans()
{
if (c1>c2) swap(c1,c2),swap(r1,r2);
yts pa,pb,pc;
pa=query(1,1,c1);
pb=query(1,c1,c2);
pc=query(1,c2,n);
if (r1==r2)
{
if (r1==0)
{
if (pb.x[0]||(pa.s[1]&&pb.v[1])||(pb.v[0]&&pc.s[0])||(pa.s[1]&&pb.x[1]&&pc.s[0])) puts("Y");
else puts("N");
}
else
{
if (pb.x[1]||(pa.s[1]&&pb.v[0])||(pb.v[1]&&pc.s[0])||(pa.s[1]&&pb.x[0]&&pc.s[0])) puts("Y");
else puts("N");
}
}
else
{
if (r1==0)
{
if (pb.v[0]||(pa.s[1]&&pb.x[1])||(pc.s[0]&&pb.x[0])) puts("Y");
else puts("N");
}
else
{
if (pb.v[1]||(pa.s[1]&&pb.x[0])||(pc.s[0]&&pb.x[1])) puts("Y");
else puts("N");
}
}
}
int main()
{
scanf("%d",&n);
build(1,1,n);
while (1)
{
scanf("%s",s);
if (s[0]=='E') break;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
r1--;r2--;
if (s[0]=='O') change(1);
else if (s[0]=='C') change(0);
else getans();
}
return 0;
}