BZOJ1018: [SHOI2008]堵塞的交通traffic
线段树
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define pii pair<int,int> #define X first #define Y second #define MAXN 100000+10 using namespace std; struct Node{ int L,R; int v[2][2]; }dat[MAXN<<2]; int n; int b[MAXN][2]; Node Merge(Node A,Node B){ if(A.L<0)return B; if(B.L<0)return A; Node ret; ret.L=A.L,ret.R=B.R; ret.v[0][0]=(A.v[0][0]&b[A.R-1][0]&B.v[0][0])|(A.v[0][1]&&b[A.R-1][1]&&B.v[1][0]); ret.v[0][1]=(A.v[0][0]&b[A.R-1][0]&B.v[0][1])|(A.v[0][1]&&b[A.R-1][1]&&B.v[1][1]); ret.v[1][0]=(A.v[1][0]&b[A.R-1][0]&B.v[0][0])|(A.v[1][1]&&b[A.R-1][1]&&B.v[1][0]); ret.v[1][1]=(A.v[1][0]&b[A.R-1][0]&B.v[0][1])|(A.v[1][1]&&b[A.R-1][1]&&B.v[1][1]); return ret; } void build(int k,int L,int R){ if(L+1==R){ dat[k].L=L,dat[k].R=R,dat[k].v[0][0]=dat[k].v[1][1]=true; return; } build(k<<1,L,(L+R)>>1); build(k<<1|1,(L+R)>>1,R); dat[k]=Merge(dat[k<<1],dat[k<<1|1]); } void update(int a,int k,bool x,bool p){ int L=dat[k].L,R=dat[k].R; int mid=(L+R)>>1; if(L+1==R){ if(p)dat[k].v[0][1]=dat[k].v[1][0]=x; return; } if(mid<=a){ update(a,k<<1|1,x,p); } else{ update(a,k<<1,x,p); } dat[k]=Merge(dat[k<<1],dat[k<<1|1]); } Node query(int a,int b,int k){ int L=dat[k].L,R=dat[k].R; int mid=(L+R)>>1; if(b<=L||R<=a){ Node ret;ret.L=-1; return ret; } else if(a<=L&&R<=b){ return dat[k]; } else{ Node lc=query(a,b,k<<1); Node rc=query(a,b,k<<1|1); return Merge(lc,rc); } } void init(){ scanf("%d",&n); build(1,1,n+1); } void solve(){ char s[10]; pii p1,p2; while(1){ scanf("%s",s); if('E'==s[0])break; scanf("%d%d%d%d",&p1.X,&p1.Y,&p2.X,&p2.Y); p1.X--,p2.X--; if(p1.Y>p2.Y){ swap(p1,p2); } if('A'==s[0]){ while(b[p1.Y-1][p1.X])p1.Y--; while(b[p2.Y][p2.X])p2.Y++; Node ans=query(p1.Y,p2.Y+1,1); printf("%c\n",(ans.v[p1.X][p2.X]?'Y':'N')); continue; } if(p1.Y==p2.Y){ update(p1.Y,1,(s[0]=='O'?true:false),true); } else{ b[p1.Y][p1.X]=(s[0]=='O'?true:false); update(p1.Y,1,(s[0]=='O'?true:false),false); } } } int main() { //freopen("data.in","r",stdin); init(); solve(); return 0; }