Description
有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入膏肓的小人国交通系统。 小人国的交通部将提供一些交通信息给你,你的任务是根据当前的交通情况回答查询的问题。交通信息可以分为以下几种格式: Close r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被堵塞了; Open r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被疏通了; Ask r1 c1 r2 c2:询问城市(r1,c1)和(r2,c2)是否连通。如果存在一条路径使得这两条城市连通,则返回Y,否则返回N;
Input
第一行只有一个整数C,表示网格的列数。接下来若干行,每行为一条交通信息,以单独的一行“Exit”作为结束。我们假设在一开始所有的道路都是堵塞的。 对30%测试数据,我们保证C小于等于1000,信息条数小于等于1000; 对100%测试数据,我们保证 C小于等于100000,信息条数小于等于100000。
Output
对于每个查询,输出一个“Y”或“N”。
Sample Input
2
Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
Sample Output
Y
N
又见恶心题
用线段树维护这一个区间四个角的连通性,这个满足区间可加性
特殊情况:询问的两个点不一定是从中间联通,它可能从外面绕一个大弯子
所以还要检查一下(1,c1)和(c2,C)的连通性
今天上午终于准备写这道恶心题了,果然恶心
无语了....最后这个错误真奇葩,虽然已经是第二次了
因为这个字符串只有4种情况,很多人应该都是判三个然后最后一个放在最后那个else那里
可是我在最后在最后那个else那里加了一句if s='A' then就神奇的从WA变成了AC(这是什么奇葩原因啊)
type
aa=array[..]of boolean;
node=record
lson,rson,left,right:longint;
flag:aa;
end;
const
maxn=;
var
tree:array[..maxn*]of node;
n,tot,x1,y1,x2,y2,ll,rr:longint;
ans,save,k1,k2:aa;
s:char; procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure build(l,r:longint);
var
mid,now:longint;
begin
inc(tot);
now:=tot;
with tree[now] do
begin
left:=l;
right:=r;
if l=r then
begin
flag[]:=true;
flag[]:=true;
exit;
end;
end;
mid:=(l+r)>>;
with tree[now] do
begin
lson:=tot+;
build(l,mid);
rson:=tot+;
build(mid+,r);
end;
end; procedure update(var a,b,c:aa);
begin
fillchar(save,sizeof(save),false);
save[]:=c[];
save[]:=c[];
if (b[] and b[] and c[])or(b[] and b[] and c[]) then save[]:=true;
if b[] or (b[] and b[] and c[] and b[] and b[]) then save[]:=true;
if (b[] and b[] and c[])or(b[] and b[] and c[]) then save[]:=true;
if c[] or (c[] and b[] and b[] and b[] and c[]) then save[]:=true;
if (b[] and b[] and c[])or(b[] and b[] and c[]) then save[]:=true;
if (b[] and b[] and c[])or(b[] and b[] and c[]) then save[]:=true;
a:=save;
end; procedure change(now:longint);
var
mid:longint;
begin
with tree[now] do
begin
if left=right then
begin
if y1=y2 then
begin
flag[]:=s='n';
flag[]:=s='n';
flag[]:=s='n';
flag[]:=s='n';
end
else flag[x1+]:=s='n';
exit;
end;
mid:=(left+right)>>;
if y1<=mid then change(lson)
else change(rson);
update(flag,tree[lson].flag,tree[rson].flag);
end;
end; procedure dfs(now:longint);
var
mid:longint;
begin
with tree[now] do
begin
if (left=ll)and(right<=rr) then
begin
ans:=flag;
exit;
end;
if (left>=ll)and(right<=rr) then
begin
update(ans,ans,flag);
exit;
end;
mid:=(left+right)>>;
if ll<=mid then dfs(lson);
if rr>mid then dfs(rson);
end;
end; procedure work;
var
i:longint;
begin
read(s);
if s='E' then halt;
if s='O' then
begin
for i:= to do
read(s);
readln(x1,y1,x2,y2);
if y1>y2 then
begin
swap(x1,x2);
swap(y1,y2);
end;
change();
end
else
if s='C' then
begin
for i:= to do
read(s);
readln(x1,y1,x2,y2);
if y1>y2 then
begin
swap(x1,x2);
swap(y1,y2);
end;
change();
end
else
if s='A' then
begin
for i:= to do
read(s);
readln(x1,y1,x2,y2);
if y1>y2 then
begin
swap(x1,x2);
swap(y1,y2);
end;
ll:=;
rr:=y1;
dfs();
k1:=ans;
ll:=y2;
rr:=n;
dfs();
k2:=ans;
ll:=y1;
rr:=y2;
dfs();
if k1[] then
begin
fillchar(k1,sizeof(k1),true);
update(ans,k1,ans);
end;
if k2[] then
begin
fillchar(k2,sizeof(k2),true);
ans[]:=true;
ans[]:=true;
update(ans,ans,k2);
end;
if x1= then
if x2= then
begin
if ans[] then writeln('Y')
else writeln('N');
end
else
begin
if ans[] then writeln('Y')
else writeln('N');
end
else
if x2= then
begin
if ans[] then writeln('Y')
else writeln('N');
end
else
begin
if ans[] then writeln('Y')
else writeln('N');
end;
end;
end; begin
readln(n);
build(,n);
while true do
work;
end.