BZOJ 1018

program bzoj1018;

type

  node=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:node;

  left,right:array [0..200001] of longint;

  stu:array [0..200001] of node;

  had: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) >>1;

    inc(tot);

    left[now]:=tot;

    build(s,mid,tot);

    inc(tot);

    right[now]:=tot;

    build(mid+1,e,tot);

end;



function update(a,b:node;had:pair):node;

var i,j,k:longint;

    now:node;

begin

  fillchar(now,sizeof(now),false);

  if had[0] and a[0] and b[0] then now[0]:=true;

  if had[1] and a[1] and b[2] then now[0]:=true;

  if had[0] and a[0] and b[1] then now[1]:=true;

  if had[1] and a[1] and b[3] then now[1]:=true;

  if had[0] and a[2] and b[0] then now[2]:=true;

  if had[1] and a[3] and b[2] then now[2]:=true;

  if had[0] and a[2] and b[1] then now[3]:=true;

  if had[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 had[0] and had[1] and b[4] then now[4]:=true;

  if b[5] then now[5]:=true;

  if b[0] and b[3] and had[0] and had[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)>>1;

  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]],had[now]);

end;



procedure insertr(w:boolean;x,y,l,r,now:longint);

var mid:longint;

begin

  mid:=(l+r)>>1;

  if x=mid then

    begin

      had[now][y]:=w;

      stu[now]:=update(stu[left[now]],stu[right[now]],had[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]],had[now]);

end;



function find(x1,x2,l,r,now:longint):node;

var temp:node;

    mid:longint;

begin

  if(x1=l)and(x2=r) then exit(stu[now]);

  mid:=(l+r)>>1;

  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]),

                             had[now])

                     );

end;



procedure main;

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;





begin

  main;

end.

BZOJ1018

你可能感兴趣的:(ZOJ)