用8个bool维护即可分别为LURU,LURD,LDRU,LDRD,LULD,RURD,Side[1],Side[2]即可。
Side表示这一块有没有接到右边。Merge一下就可以了。码农题,WA了一次,发现未初始化,就AC了。。
1 #include <cstdio> 2 inline int Min(int x,int y) {return x>y?y:x;} 3 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;} 4 inline void Get_Int(int &x) 5 { 6 char ch=getchar(); x=0; 7 while (ch<'0' || ch>'9') ch=getchar(); 8 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 9 } 10 //======================================== 11 const int Maxn=100100; 12 struct Node 13 { 14 bool LURU,LURD,LDRU,LDRD,LULD,RURD,Side[3]; 15 }Tree[Maxn<<2],Null; 16 int x1,y1,x2,y2,n; 17 char ch[20]; 18 inline Node Merge(Node L,Node R) 19 { 20 Node Ret; Ret=Null; 21 Ret.Side[1]=R.Side[1],Ret.Side[2]=R.Side[2]; 22 if ((L.LURU&&R.LURU&&L.Side[1]) || (L.LURD&&R.LDRU&&L.Side[2])) Ret.LURU=true; 23 if ((L.LDRD&&R.LDRD&&L.Side[2]) || (L.LDRU&&R.LURD&&L.Side[1])) Ret.LDRD=true; 24 if ((L.LURU&&R.LURD&&L.Side[1]) || (L.LURD&&R.LDRD&&L.Side[2])) Ret.LURD=true; 25 if ((L.LDRD&&R.LDRU&&L.Side[2]) || (L.LDRU&&R.LURU&&L.Side[1])) Ret.LDRU=true; 26 if (L.LULD || (L.LURU&&L.LDRD&&R.LULD&&L.Side[1]&&L.Side[2])) Ret.LULD=true; 27 if (R.RURD || (R.LURU&&R.LDRD&&L.RURD&&L.Side[1]&&L.Side[2])) Ret.RURD=true; 28 return Ret; 29 } 30 void Build(int o,int l,int r) 31 { 32 33 if (l==r) 34 { 35 Tree[o].LURU=Tree[o].LDRD=true; 36 return; 37 } 38 int mid=(l+r)>>1; 39 Build(o<<1,l,mid),Build(o<<1|1,mid+1,r); 40 Tree[o]=Merge(Tree[o<<1],Tree[o<<1|1]); 41 } 42 void Modify_X(int o,int l,int r,int pos,bool kind) 43 { 44 if (l==r) 45 { 46 Tree[o].LULD=Tree[o].RURD=Tree[o].LURD=Tree[o].LDRU=kind; 47 return; 48 } 49 int mid=(l+r)>>1; 50 if (pos<=mid) Modify_X(o<<1,l,mid,pos,kind); else Modify_X(o<<1|1,mid+1,r,pos,kind); 51 Tree[o]=Merge(Tree[o<<1],Tree[o<<1|1]); 52 } 53 void Modify_Y(int o,int l,int r,int pos,int x,bool kind) 54 { 55 if (l==r) 56 { 57 Tree[o].Side[x]=kind; 58 return; 59 } 60 int mid=(l+r)>>1; 61 if (pos<=mid) Modify_Y(o<<1,l,mid,pos,x,kind); else Modify_Y(o<<1|1,mid+1,r,pos,x,kind); 62 Tree[o]=Merge(Tree[o<<1],Tree[o<<1|1]); 63 } 64 inline void Close() 65 { 66 if (x1==x2) Modify_Y(1,1,n,Min(y1,y2),x1,false); 67 if (y1==y2) Modify_X(1,1,n,y1,false); 68 } 69 inline void Open() 70 { 71 if (x1==x2) Modify_Y(1,1,n,Min(y1,y2),x1,true); 72 if (y1==y2) Modify_X(1,1,n,y1,true); 73 } 74 Node Query(int o,int l,int r,int p,int q) 75 { 76 if (l==p && r==q) 77 { 78 Node Ret=Tree[o]; 79 return Ret; 80 } 81 int mid=(l+r)>>1; 82 if (q<=mid) return Query(o<<1,l,mid,p,q); 83 if (p>=mid+1) return Query(o<<1|1,mid+1,r,p,q); 84 if (p<=mid && q>=mid+1) 85 return Merge(Query(o<<1,l,mid,p,mid),Query(o<<1|1,mid+1,r,mid+1,q)); 86 } 87 inline bool Check() 88 { 89 if (y1>y2) Swap(y1,y2),Swap(x1,x2); 90 Node Pre,Suf,Now; 91 if (y1-1>=1) Pre=Query(1,1,n,1,y1-1); else Pre=Null; 92 if (y2+1<=n) Suf=Query(1,1,n,y2+1,n); else Suf=Null; 93 Now=Query(1,1,n,y1,y2); 94 if (x1==x2) 95 { 96 if ((x1==1) && ((Now.LURU) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRU) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LURD) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRD))) return true; 97 if ((x1==2) && ((Now.LDRD) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LURD) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LDRU) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LURU))) return true; 98 } else 99 { 100 if ((x1==1 && x2==2) && ((Now.LURD) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRD) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LURU) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRU))) return true; 101 if ((x1==2 && x2==1) && ((Now.LDRU) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LURU) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LDRD) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LURD))) return true; 102 } 103 return false; 104 } 105 inline void Ask() {if (Check()) puts("Y"); else puts("N");} 106 int main() 107 { 108 // freopen("c.in","r",stdin); 109 Get_Int(n); Build(1,1,n); 110 Null.LURU=Null.LURD=Null.LDRU=Null.LDRD=Null.Side[1]=Null.Side[2]=Null.LULD=Null.RURD=false; 111 while (scanf("%s",ch)!=EOF) 112 { 113 if (ch[0]=='E') break; 114 Get_Int(x1),Get_Int(y1),Get_Int(x2),Get_Int(y2); 115 if (ch[0]=='O') Open(); 116 if (ch[0]=='C') Close(); 117 if (ch[0]=='A') Ask(); 118 } 119 return 0; 120 }