现在的位置: 首页 > 综合 > 正文

bzoj1018

2017年11月17日 ⁄ 综合 ⁄ 共 3728字 ⁄ 字号 评论关闭

1018: [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit:
162 MB
Submit: 617  Solved: 165
[Submit][Status][Discuss]

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

线段树维护连通性……

需要注意联通可能绕一大圈联通= =,一开始没想到挂到死……ORZ

program bzoj1018;
type
  group=array [0..5] of boolean;
  pair=array [0..1] of boolean;
var
  tot,c,i,j,k,x1,y1,x2,y2:longint;
  ans:boolean;
  ch:char;
  x,y,z:group;
  left,right:array [0..200001] of longint;
  stu:array [0..200001] of group;
  www:array [0..200001]of pair;

procedure swap (var a,b:longint);
begin
  if a=b then exit;
  a:=a xor b;
  b:=a xor b;
  a:=a xor b;
end;

procedure build (s,e,now:longint);
var
  mid:longint;
begin
  if s=e then
    begin
      stu[now][0]:=true;
      stu[now][3]:=true;
      exit;
    end;
  mid:=(s+e) div 2;
  inc(tot);
  left[now]:=tot;
  build(s,mid,tot);
  inc(tot);
  right[now]:=tot;
  build(mid+1,e,tot);
end;

function update (a,b:group;www:pair):group;
var
  i,j,k:longint;
  now:group;
begin
  fillchar(now,sizeof(now),false);
  if www[0] and a[0] and b[0] then now[0]:=true;
  if www[1] and a[1] and b[2] then now[0]:=true;
  if www[0] and a[0] and b[1] then now[1]:=true;
  if www[1] and a[1] and b[3] then now[1]:=true;
  if www[0] and a[2] and b[0] then now[2]:=true;
  if www[1] and a[3] and b[2] then now[2]:=true;
  if www[0] and a[2] and b[1] then now[3]:=true;
  if www[1] and a[3] and b[3] then now[3]:=true;

  if a[4] then now[4]:=true;
  if a[0] and a[3] and www[0] and www[1] and b[4] then now[4]:=true;

  if b[5] then now[5]:=true;
  if b[0] and b[3] and www[0] and www[1] and a[5] then now[5]:=true;

  exit(now);
end;

procedure insertl (w:boolean;x,l,r,now:longint);
var
  mid:longint;
begin
  if l=r then
    begin
      if w then
        fillchar(stu[now],sizeof(stu[now]),true)
           else
        begin
          fillchar(stu[now],sizeof(stu[now]),false);
          stu[now][0]:=true;
          stu[now][3]:=true;
        end;
      exit;
    end;
  mid:=(l+r) div 2;
  if x<=mid then insertl(w,x,l,mid,left[now])
            else insertl(w,x,mid+1,r,right[now]);
  stu[now]:=update(stu[left[now]],stu[right[now]],www[now]);
end;

procedure insertr (w:boolean;x,y,l,r,now:longint);
var
  mid:longint;
begin
  mid:=(l+r) div 2;
  if x=mid then
    begin
      www[now][y]:=w;
      stu[now]:=update(stu[left[now]],stu[right[now]],www[now]);
      exit;
    end;
  if x<=mid then insertr(w,x,y,l,mid,left[now])
            else insertr(w,x,y,mid+1,r,right[now]);
  stu[now]:=update(stu[left[now]],stu[right[now]],www[now]);
end;

function find (x1,x2,l,r,now:longint):group;
var
  temp:group;
  mid:longint;
begin
  if (x1=l)and(x2=r) then exit(stu[now]);
  mid:=(l+r) div 2;
  if x2<=mid then exit(find(x1,x2,l,mid,left[now]))
             else
  if x1>mid then exit(find(x1,x2,mid+1,r,right[now]))
            else exit(
                      update(find(x1,mid,l,mid,left[now]),
                             find(mid+1,x2,mid+1,r,right[now]),
                             www[now])
                     );
end;

begin
  readln(c);
  build(1,c,0);
  repeat
    read(ch);
    case ch of
      'E':break;
      'O':begin
            read(ch,ch,ch,y1,x1,y2,x2);
            dec(y1);
            dec(y2);
            if x1=x2 then insertl(true,x1,1,c,0)
                     else
            if x1<x2 then insertr(true,x1,y1,1,c,0)
                     else insertr(true,x2,y1,1,c,0);
          end;
      'C':begin
            read(ch,ch,ch,ch,y1,x1,y2,x2);
            dec(y1);
            dec(y2);
            if x1=x2 then insertl(false,x1,1,c,0)
                     else
            if x1<x2 then insertr(false,x1,y1,1,c,0)
                     else insertr(false,x2,y1,1,c,0);
          end;
      'A':begin
            read(ch,ch,y1,x1,y2,x2);
            dec(y1);
            dec(y2);
            if x1>x2 then
              begin
                swap(x1,x2);
                swap(y1,y2);
              end;
            x:=find(1,x1,1,c,0);
            y:=find(x1,x2,1,c,0);
            z:=find(x2,c,1,c,0);
            ans:=false;
            ans:=ans or y[y1*2+y2];
            ans:=ans or (x[5] and y[(1-y1)*2+y2]);
            ans:=ans or (z[4] and y[y1*2+1-y2]);
            ans:=ans or (x[5] and z[4] and y[(1-y1)*2+1-y2]);
            if ans then writeln('Y')
                   else writeln('N');
          end;
    end;
  until false;
end.
【上篇】
【下篇】

抱歉!评论已关闭.