bzoj 1018: [SHOI2008]堵塞的交通traffic
由于只有两行,对一个区间可以维护四个角上的连通性 一共6个量,满足区间可加性,用线段树维护,查询时找出3段的量,看是否满足题解上的三种情况之一。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<queue> 7 #include<algorithm> 8 #include<vector> 9 #define M 1000009 10 #define EPS 1e-10 11 #define MO 19650827 12 #define ll long long 13 using namespace std; 14 ll read() 15 { 16 char ch=getchar(); 17 ll x=0,f=1; 18 for(;ch<'0'||ch>'9';ch=getchar()) 19 if(ch=='-') 20 f=-1; 21 for(;ch>='0'&&ch<='9';ch=getchar()) 22 x=x*10+ch-'0'; 23 return x*f; 24 } 25 int n,mp[M]; 26 struct data 27 { 28 bool f[6]; 29 }s[10],a[M]; 30 void build(int x,int l,int r) 31 { 32 if(l==r) 33 { 34 a[x]=s[0]; 35 return; 36 } 37 int mid=(l+r)>>1; 38 build(x*2,l,mid); 39 build(x*2+1,mid+1,r); 40 } 41 int calc(int x,int y) 42 { 43 return x*(n-1)+y; 44 } 45 data he(data a,data b,int x,int y) 46 { 47 data c; 48 c.f[0]=((a.f[0]&&x&&b.f[0])||(a.f[4]&&y&&b.f[5])); 49 c.f[1]=((a.f[1]&&y&&b.f[1])||(a.f[5]&&x&&b.f[4])); 50 c.f[2]=(a.f[2]||(a.f[0]&&x&&b.f[2]&&y&&a.f[1])); 51 c.f[3]=(b.f[3]||(b.f[0]&&x&&a.f[3]&&y&&b.f[1])); 52 c.f[4]=((a.f[4]&&y&&b.f[1])||(a.f[0]&&x&&b.f[4])); 53 c.f[5]=((a.f[5]&&x&&b.f[0])||(a.f[1]&&y&&b.f[5])); 54 return c; 55 } 56 void gai(int x,int l,int r,int x1,int y1,int x2,int c) 57 { 58 int mid=(l+r)>>1; 59 if(x1==x2&&mid==y1) 60 { 61 mp[calc(x1,y1)]=c; 62 a[x]=he(a[x*2],a[x*2+1],mp[calc(0,y1)],mp[calc(1,y1)]); 63 return; 64 } 65 if(l==r) 66 { 67 mp[calc(2,y1)]=c; 68 a[x]=s[c]; 69 return; 70 } 71 if(y1<=mid) 72 gai(x*2,l,mid,x1,y1,x2,c); 73 else 74 gai(x*2+1,mid+1,r,x1,y1,x2,c); 75 a[x]=he(a[x*2],a[x*2+1],mp[calc(0,mid)],mp[calc(1,mid)]); 76 } 77 data query(int x,int l,int r,int L,int R) 78 { 79 int mid=(l+r)>>1; 80 if(L<=l&&R>=r) 81 return a[x]; 82 if(R<=mid) 83 return query(x*2,l,mid,L,R); 84 if(L>mid) 85 return query(x*2+1,mid+1,r,L,R); 86 return he(query(x*2,l,mid,L,R),query(x*2+1,mid+1,r,L,R),mp[calc(0,mid)],mp[calc(1,mid)]); 87 } 88 void xun(int x1,int y1,int x2,int y2) 89 { 90 s[2]=query(1,1,n,1,y1); 91 s[3]=query(1,1,n,y1,y2); 92 s[4]=query(1,1,n,y2,n); 93 int ans; 94 if(x1==x2) 95 ans=(s[3].f[x1]||(s[2].f[3]&&s[3].f[4+x1^1])||(s[3].f[4+x1]&&s[4].f[2])||(s[2].f[3]&&s[3].f[x1^1]&&s[4].f[2])); 96 else 97 ans=(s[3].f[4+x1]||(s[2].f[3]&&s[3].f[x1^1])||(s[3].f[x1]&&s[4].f[2])||(s[2].f[3]&&s[3].f[4+x1^1]&&s[4].f[2])); 98 if(ans) 99 printf("Y\n"); 100 else 101 printf("N\n"); 102 } 103 int main() 104 { 105 s[0]=(data){1,1,0,0,0,0}; 106 s[1]=(data){1,1,1,1,1,1}; 107 n=read(); 108 build(1,1,n); 109 for(;;) 110 { 111 char ch[10]; 112 scanf("%s",ch); 113 if(ch[0]=='E') 114 return 0; 115 int x1=read(),y1=read(),x2=read(),y2=read(); 116 x1--; 117 x2--; 118 if(y1>y2) 119 { 120 swap(y1,y2); 121 swap(x1,x2); 122 } 123 if(ch[0]=='O') 124 gai(1,1,n,x1,y1,x2,1); 125 if(ch[0]=='C') 126 gai(1,1,n,x1,y1,x2,0); 127 if(ch[0]=='A') 128 xun(x1,y1,x2,y2); 129 } 130 return 0; 131 } 132