@ysner
2018-04-24T22:13:16.000000Z
字数 2854
阅读 1900
线段树
给一个网格,每次把相邻两点连通性改为或,询问两点是否联通。
线段树神题。。。
码量巨大,细节巨多。。。
从一座城市走到另一座城市,一共有4种方案。
图
若两城市在同一行(比如说,),那么:
s1-->s2
s1-->s3,s3-->s2
s1-->s4,s4-->s2
s1-->s3,s3-->s4,s4-->s2
图
若两城市不在同一行(比如说,),那么:
s1-->s3,s3-->s4
s1-->s2,s2-->s4
s1-->s3,s3-->s2,s2-->s4
s1-->s4
图
而我们怎么维护这个东西呢?考虑用线段树。每个节点表示区间[l,r]的矩形,并且记录8个变量:。其中,:
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define ls x<<1
#define rs x<<1|1
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=1e6+100;
struct way{int l,r;}a[N<<2];
struct seg{int U,D,l,r,u,d,p,q;}t[N<<2];
int c,r1,r2,c1,c2;
char s[10];
il int gi()
{
re int x=0,t=1;
re char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*t;
}
il void Merge(seg &x,seg l,seg r)
{
x.l=l.l|(l.u&x.U&r.l&x.D&l.d);
x.r=r.r|(r.u&x.U&l.r&x.D&r.d);
x.u=(l.u&x.U&r.u)|(l.q&x.D&r.p);
x.d=(l.d&x.D&r.d)|(l.p&x.U&r.q);
x.q=(l.u&x.U&r.q)|(l.q&x.D&r.d);
x.p=(l.d&x.D&r.p)|(l.p&x.U&r.u);
}
il void Build(re int x,re int l,re int r)
{
a[x]=(way){l,r};re int mid=l+r>>1;
if(l==r) {t[x].U=t[x].D=t[x].u=t[x].d=1;return;}
Build(ls,l,mid);Build(rs,mid+1,r);
}
il void Updater(re int x,re int p,re int y,re int w)
{
re int l=a[x].l,r=a[x].r;re int mid=l+r>>1;
if(p==mid)
{
if(y==1) t[x].U=w;else t[x].D=w;
Merge(t[x],t[ls],t[rs]);
return;
}
if(p<=mid) Updater(ls,p,y,w);else Updater(rs,p,y,w);
Merge(t[x],t[ls],t[rs]);
}
il void Updatec(re int x,re int p,re int w)
{
re int l=a[x].l,r=a[x].r;re int mid=l+r>>1;
if(l==r) {t[x].l=t[x].r=t[x].p=t[x].q=w;return;}
if(p<=mid) Updatec(ls,p,w);else Updatec(rs,p,w);
Merge(t[x],t[ls],t[rs]);
}
seg Query(re int x,re int ql,re int qr)
{
re int l=a[x].l,r=a[x].r;re int mid=l+r>>1;
if(ql<=l&&r<=qr) return t[x];
if(qr<=mid) return Query(ls,ql,qr);
else if(ql>mid) return Query(rs,ql,qr);
else
{
seg res=t[x];
Merge(res,Query(ls,ql,qr),Query(rs,ql,qr));
return res;
}
}
int main()
{
c=gi();
Build(1,1,c);
while(233)
{
scanf("%s",s);
if(s[0]=='E') break;
r1=gi();c1=gi();r2=gi();c2=gi();
if(c1>c2) swap(c1,c2),swap(r1,r2);
if(s[0]=='O')
if(r1==r2) Updater(1,c1,r1,1);else Updatec(1,c1,1);
if(s[0]=='C')
if(r1==r2) Updater(1,c1,r1,0);else Updatec(1,c1,0);
if(s[0]=='A')
{
seg l=Query(1,1,c1),x=Query(1,c1,c2),r=Query(1,c2,c);
re int ans=0;
if(r1==1&&r2==1)
ans=x.u|(l.r&x.p)|(x.q&r.l)|(l.r&x.d&r.l);
if(r1==1&&r2==2)
ans=x.q|(l.r&x.d)|(x.u&r.l)|(l.r&x.p&r.l);
if(r1==2&&r2==1)
ans=x.p|(l.r&x.u)|(x.d&r.l)|(l.r&x.q&r.l);
if(r1==2&&r2==2)
ans=x.d|(l.r&x.q)|(x.p&r.l)|(l.r&x.u&r.l);
puts(ans?"Y":"N");
}
}
return 0;
}