线段树有这种姿势啊。。是我太菜了。。。
一开始简直被吓呆了,总感觉要写好多。。很烦。。。对着某个题解盯了半天才敢写QAQ
然后我发现很赞啊
幸好发现了这篇233 参考了他的写法 (我基本上是抄他的
用一个数组
a[i][j]
,维护从
x
节点最左端的
另一个数组
转移大概就是各种讨论吧,画画图什么的….
然后我就在2k左右的代码就解决这题啦~ 时间也很可观
大家也可以参考参考我的代码QAQ,写的短的感觉真不错233
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+3,inf=1e9+7;
inline int read(){
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
struct mt{bool a[2][2],v[2];}s[N]; int n;
mt upd(mt s1,mt s2,bool b[]){
mt g;
for(int i=0;i<2;++i)for(int j=0;j<2;++j)
g.a[i][j]= s1.a[i][0] && b[0] && s2.a[0][j] || s1.a[i][1] && b[1] && s2.a[1][j];
g.v[0]=s1.v[0] || s1.a[0][0] && b[0] && s2.v[0] && s1.a[1][1] && b[1];
g.v[1]=s2.v[1] || s2.a[0][0] && b[0] && s1.v[1] && s2.a[1][1] && b[1];
return g;
}
bool b[N][2]; int X1,Y1,X2,Y2;
mt access(int x,int l,int r,int ql,int qr){
if(l==ql && r==qr) return s[x];
int mid=l+r>>1;
if(qr<=mid) return access(x<<1,l,mid,ql,qr);
if(ql>mid) return access(x<<1|1,mid+1,r,ql,qr);
return upd(access(x<<1,l,mid,ql,mid),access(x<<1|1,mid+1,r,mid+1,qr),b[x]);
}
void bulid(int x,int l,int r){
if(l==r) s[x].a[0][0]=s[x].a[1][1]=1;
else {int mid=l+r>>1; bulid(x<<1,l,mid),bulid(x<<1|1,mid+1,r);}
}
void change(int x,int l,int r,int u){
int mid=l+r>>1,lc=x<<1,rc=lc|1;
if(X1==X2 && Y1==mid){
b[x][X1]=u; s[x]=upd(s[lc],s[rc],b[x]);
}
else if(l==r) s[x].a[0][1]=s[x].a[1][0]=s[x].v[0]=s[x].v[1]=u;
else{
if(Y2<=mid) change(lc,l,mid,u); else change(rc,mid+1,r,u);
s[x]=upd(s[lc],s[rc],b[x]);
}
}
void ask(){
mt L=access(1,1,n,1,Y1),R=access(1,1,n,Y2,n),M=access(1,1,n,Y1,Y2);
bool g=0;
for(int i=0;i<2;++i)for(int j=0;j<2;++j)
if(M.a[i][j] && (i==X1||L.v[1]) && (j==X2||R.v[0])){g=1; break;}
puts(g?"Y":"N");
}
int main(){
n=read(); bulid(1,1,n);
while(1){
char c[10]; scanf("%s",c);
if(c[0]=='E')return 0;
X1=read()-1,Y1=read(),X2=read()-1,Y2=read();
if(Y1>Y2) swap(X1,X2),swap(Y1,Y2);
if(c[0]=='A') ask();
else change(1,1,n,c[0]=='O');
}
return 0;
}