1018: [SHOI2008]堵塞的交通traffic

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 }

猜你喜欢

转载自www.cnblogs.com/mjtcn/p/10102125.html