1018: [SHOI2008]堵塞的交通traffic
分析:
用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可。
六种情况左上到右上(左边到右边的情况)……,左上到左下(同一侧相互到达的情况)……
同一侧相互到达的情况,查询[l,r]是查的不完全。因为还有可能是先往左边走几步,下去,在走回来。这时候,查询一下[1,l]的情况,或起来即可。
代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #define fi(s) freopen(s,"r",stdin); 12 #define fo(s) freopen(s,"w",stdout); 13 using namespace std; 14 typedef long long LL; 15 16 inline int read() { 17 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1; 18 for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f; 19 } 20 21 #define Root 1, n, 1 22 #define lson l, mid, rt << 1 23 #define rson mid + 1, r, rt << 1 | 1 24 25 const int N = 100005; 26 27 struct Node{ 28 bool l, r, s, x, a, b, t[2]; 29 Node () {l = r = s = x = a = b = t[0] = t[1] = 0; } 30 }T[N << 2]; 31 int n, A1, A2, B1, B2; 32 33 Node operator + (const Node &p, const Node &q) { 34 Node ans; 35 ans.t[0] = q.t[0], ans.t[1] = q.t[1]; 36 if (p.l || (p.s && p.t[0] && q.l && p.t[1] && p.x)) ans.l = 1; 37 if (q.r || (q.s && p.t[0] && p.r && p.t[1] && q.x)) ans.r = 1; 38 if ((p.s && p.t[0] && q.s) || (p.b && p.t[1] && q.a)) ans.s = 1; 39 if ((p.x && p.t[1] && q.x) || (p.a && p.t[0] && q.b)) ans.x = 1; 40 if ((p.x && p.t[1] && q.a) || (p.a && p.t[0] && q.s)) ans.a = 1; 41 if ((p.s && p.t[0] && q.b) || (p.b && p.t[1] && q.x)) ans.b = 1; 42 return ans; 43 } 44 void build(int l,int r,int rt) { 45 if (l == r) { 46 T[rt].s = T[rt].x = 1; return ; 47 } 48 int mid = (l + r) >> 1; 49 build(lson); build(rson); 50 T[rt] = T[rt << 1] + T[rt << 1 | 1]; 51 } 52 void update1(int l,int r,int rt,int p,int opt) { 53 if (l == r) { 54 T[rt].t[A1 - 1] = opt; return; 55 } 56 int mid = (l + r) >> 1; 57 if (p <= mid) update1(lson, p, opt); 58 else update1(rson, p, opt); 59 T[rt] = T[rt << 1] + T[rt << 1 | 1]; 60 } 61 void update2(int l,int r,int rt,int p,int opt) { 62 if (l == r) { 63 T[rt].l = T[rt].r = T[rt].a = T[rt].b = opt; 64 return ; 65 } 66 int mid = (l + r) >> 1; 67 if (p <= mid) update2(lson, p, opt); 68 else update2(rson, p, opt); 69 T[rt] = T[rt << 1] + T[rt << 1 | 1]; 70 } 71 Node query(int l,int r,int rt,int L,int R) { 72 if (L <= l && r <= R) { 73 return T[rt]; 74 } 75 int mid = (l + r) >> 1; 76 if (L > mid) return query(rson, L, R); // 注意这里的返回值,不能直接用一个ans来加 77 else if (R <= mid) return query(lson, L, R); 78 else return query(lson, L, R) + query(rson, L, R); 79 } 80 bool solve() { 81 int L = query(Root, 1, B1).r; 82 int R = query(Root, B2, n).l; 83 Node now = query(Root, B1, B2); 84 if (A1 == A2) { 85 if ((A1 == 1) && (now.s || (L && now.a) || (now.b && R) || (L && now.x && R))) return 1; // A1的判断!!! 86 if ((A1 == 2) && (now.x || (L && now.b) || (now.a && R) || (L && now.s && R))) return 1; 87 } else { 88 if ((A1 == 1) && (now.b || (now.s && R) || (L && now.x) || (L && now.a && R))) return 1; 89 if ((A1 == 2) && (now.a || (now.x && R) || (L && now.s) || (L && now.b && R))) return 1; 90 } 91 return 0; 92 } 93 int main() { 94 n = read(); char opt[10]; 95 build(Root); 96 while (true) { 97 scanf("%s", opt); 98 if (opt[0] == ‘E‘) break; 99 A1 = read(), B1 = read(), A2 = read(), B2 = read(); 100 if (B1 > B2) swap(A1, A2), swap(B1, B2); 101 if (opt[0] == ‘A‘) puts(solve() ? "Y" : "N"); 102 else { 103 if (B1 != B2) update1(Root, B1, opt[0] == ‘O‘ ? 1 : 0); 104 else update2(Root, B1, opt[0] == ‘O‘ ? 1 : 0); 105 } 106 } 107 return 0; 108 }
原文地址:https://www.cnblogs.com/mjtcn/p/10102125.html
时间: 2024-10-21 22:47:08