1 #include <bits/stdc++.h>
2 using namespace std;
3
4 const int maxn=1e5+5;
5 int n,cnt;
6 char s[10];
7 bool A[maxn][2];
8 struct node{
9 bool a[2][2];
10 node(){
11 a[0][0]=a[0][1]=a[1][0]=a[1][1]=false;
12 }
13 bool* operator [] (int id){return a[id];}
14 }a[maxn<<4];
15 struct Segment_tree{
16 node merge(bool *a,node x,node y){
17 node t;
18 t[0][0]=(x[0][0]&a[0]&y[0][0])|(x[0][1]&a[1]&y[1][0]);
19 t[0][1]=(x[0][0]&a[0]&y[0][1])|(x[0][1]&a[1]&y[1][1]);
20 t[1][0]=(x[1][0]&a[0]&y[0][0])|(x[1][1]&a[1]&y[1][0]);
21 t[1][1]=(x[1][1]&a[1]&y[1][1])|(x[1][0]&a[0]&y[0][1]);
22 return t;
23 }
24 void build_tree(int l,int r,int k){
25 if(l==r){a[k][0][0]=a[k][1][1]=true;return;}
26 int mid=l+(r-l)/2;
27 build_tree(l,mid,k<<1); build_tree(mid+1,r,k<<1|1);
28 }
29 void update(int l,int r,int k,int pos,bool op,bool dir){
30 if(l==r){
31 if(dir) a[k][0][1]=a[k][1][0]=op;//c
32 return;
33 }
34 int mid=l+(r-l)/2;
35 if(!dir&&pos==mid){//r
36 a[k]=merge(A[mid],a[k<<1],a[k<<1|1]);
37 return;
38 }
39 if(pos<=mid) update(l,mid,k<<1,pos,op,dir);
40 else update(mid+1,r,k<<1|1,pos,op,dir);
41 a[k]=merge(A[mid],a[k<<1],a[k<<1|1]);
42 }
43 void _get_right(int l,int r,int k,int &pos,node &t,bool dir){
44 if(l==r) return;
45 int mid=l+(r-l)/2;
46 node tmp=merge(A[l-1],t,a[k<<1]);
47 if(tmp[dir][0]||tmp[dir][1]) pos=mid, t=tmp, _get_right(mid+1,r,k<<1|1,pos,t,dir);
48 else _get_right(l,mid,k<<1,pos,t,dir);
49 }
50 void _get_left(int l,int r,int k,int &pos,node &t,bool dir){
51 if(l==r) return;
52 int mid=l+(r-l)/2;
53 node tmp=merge(A[r],a[k<<1|1],t);
54 if(tmp[0][dir]||tmp[1][dir]) pos=mid+1,t=tmp, _get_left(l,mid,k<<1,pos,t,dir);
55 else _get_left(mid+1,r,k<<1|1,pos,t,dir);
56 }
57 void get_right(int l,int r,int k,int &pos,node &t,bool dir){
58 if(l==r) {t=a[k];return;}
59 int mid=l+(r-l)/2;
60 if(pos>mid) get_right(mid+1,r,k<<1|1,pos,t,dir);
61 else{
62 get_right(l,mid,k<<1,pos,t,dir);
63 if(pos!=mid) return;
64 node tmp=merge(A[mid],t,a[k<<1|1]);
65 if(tmp[dir][0]||tmp[dir][1]) pos=r,t=tmp;
66 else _get_right(mid+1,r,k<<1|1,pos,t,dir);
67 }
68 }
69 void get_left(int l,int r,int k,int &pos,node &t,bool dir){
70 if(l==r) {t=a[k];return;}
71 int mid=l+(r-l)/2;
72 if(pos<=mid) get_left(l,mid,k<<1,pos,t,dir);
73 else{
74 get_left(mid+1,r,k<<1|1,pos,t,dir);
75 if(pos!=mid+1) return;
76 node tmp=merge(A[mid],a[k<<1],t);
77 if(tmp[0][dir]||tmp[1][dir]) pos=l,t=tmp;
78 else _get_left(l,mid,k<<1,pos,t,dir);
79 }
80 }
81 node get_ans(int l,int r,int k,int x,int y){
82 if(l==x&&r==y) return a[k];
83 int mid=l+(r-l)/2;
84 if(y<=mid) return get_ans(l,mid,k<<1,x,y);
85 if(x>mid) return get_ans(mid+1,r,k<<1|1,x,y);
86 return merge(A[mid],get_ans(l,mid,k<<1,x,mid),get_ans(mid+1,r,k<<1|1,mid+1,y));
87 }
88 }t;
89 void update(int x1,int y1,int x2,int y2,bool op){
90 if(x1==x2){//r
91 if(y1>y2) swap(y1,y2);
92 A[y1][x1]=op;
93 t.update(1,n,1,y1,op,false);
94 }
95 else t.update(1,n,1,y1,op,true);//c
96 }
97 void query(int x1,int y1,int x2,int y2){
98 if(y1>y2) swap(x1,x2), swap(y1,y2);
99 node tmp1;
100 t.get_left(1,n,1,y1,tmp1,x1);
101 x1=tmp1[0][x1]?0:1;
102 node tmp2;
103 t.get_right(1,n,1,y2,tmp2,x2);
104 x2=tmp2[x2][0]?0:1;
105 node tmp=t.get_ans(1,n,1,y1,y2);
106 puts(tmp[x1][x2]?"Y":"N");
107
108 }
109 int main(){
110 int x1,y1,x2,y2;
111 scanf("%d",&n);
112 t.build_tree(1,n,1);
113 while(true){
114 scanf("%s",s);
115 if(s[0]==‘C‘) scanf("%d%d%d%d",&x1,&y1,&x2,&y2), update(x1-1,y1,x2-1,y2,false);
116 else if(s[0]==‘O‘) scanf("%d%d%d%d",&x1,&y1,&x2,&y2), update(x1-1,y1,x2-1,y2,true);
117 else if(s[0]==‘A‘) scanf("%d%d%d%d",&x1,&y1,&x2,&y2), query(x1-1,y1,x2-1,y2);
118 else if(s[0]==‘E‘) break;
119 }
120 return 0;
121 }