bzoj1018

1018: [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit: 162 MB
Submit: 2208  Solved: 687
[Submit][Status][Discuss]

Description

有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入膏肓的小人国交通系统。 小人国的交通部将提供一些交通信息给你,你的任务是根据当前的交通情况回答查询的问题。交通信息可以分为以下几种格式: Close r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被堵塞了; Open r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被疏通了; Ask r1 c1 r2 c2:询问城市(r1,c1)和(r2,c2)是否连通。如果存在一条路径使得这两条城市连通,则返回Y,否则返回N;

Input

第一行只有一个整数C,表示网格的列数。接下来若干行,每行为一条交通信息,以单独的一行“Exit”作为结束。我们假设在一开始所有的道路都是堵塞的。 对30%测试数据,我们保证C小于等于1000,信息条数小于等于1000; 对100%测试数据,我们保证 C小于等于100000,信息条数小于等于100000。

Output

对于每个查询,输出一个“Y”或“N”。

Sample Input

2
Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit

Sample Output

Y
N

HINT

Source

题意:显然

分析:这题的思路是很容易想到的,可以用线段树来维护某一段四个端点之间的连通性,维护是显然的

但是,有可能出现这种恶心情况

1-2-3

|  |  |

4-5-6

T_T

无泪哭

所以需要4*4的矩阵维护四个端点之间的连通性,

所以更新是很容易的

但是询问就要这样了

首先假设询问(Lx, Rx)这段区间的连通性

那么先查询1-Lx的连通性,先知晓第Lx列的连通性

然后查询Rx-n的连通性,知晓第Rx列的连通性

然后查询Lx-Rx的连通性,用这三块东西并起来求答案

这样就可以了

综上所述,本题得解

T_T

我的代码不知为何RE

太坑了

。。。。。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <deque>
  6 #include <vector>
  7 #include <queue>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <map>
 11 #include <set>
 12 #include <ctime>
 13 using namespace std;
 14 typedef long long LL;
 15 #define For(i, s, t) for(int i = (s); i <= (t); i++)
 16 #define Ford(i, s, t) for(int i = (s); i >= (t); i--)
 17 #define Rep(i, t) for(int i = (0); i < (t); i++)
 18 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--)
 19 #define MIT (2147483647)
 20 #define INF (1000000001)
 21 #define MLL (1000000000000000001LL)
 22 #define sz(x) ((bnt) (x).size())
 23 #define clr(x, y) memset(x, y, sizeof(x))
 24 #define puf push_front
 25 #define pub push_back
 26 #define pof pop_front
 27 #define pob pop_back
 28 #define ft first
 29 #define sd second
 30 #define mk make_pair
 31 inline void SetIO(string Name) {
 32     string Input = Name+".in",
 33     Output = Name+".out";
 34     freopen(Input.c_str(), "r", stdin),
 35     freopen(Output.c_str(), "w", stdout);
 36 }
 37
 38 const int N = 100010;
 39 struct State {
 40     bool Connect[4][4];
 41
 42     State() {
 43         clr(Connect, 0);
 44     }
 45
 46     inline void Gone() {
 47         Rep(k, 4)
 48             Rep(i, 4)
 49                 Rep(j, 4) Connect[i][j] |= Connect[i][k]&Connect[k][j];
 50     }
 51
 52     inline void Add(State &A) {
 53         Rep(i, 4)
 54             Rep(j, 4) Connect[i][j] |= A.Connect[i][j];
 55     }
 56
 57     inline void Check() {
 58         Rep(i, 4)
 59             Rep(j, 4) Connect[i][j] |= Connect[j][i];
 60     }
 61
 62     inline State operator +(State B) {
 63         State Ret, A;
 64         Rep(i, 4)
 65             Rep(j, 4) A.Connect[i][j] = Connect[i][j];
 66         Rep(i, 2)
 67             Rep(j, 2) {
 68                 bool T = A.Connect[i+2][j+2]|B.Connect[i][j];
 69                 A.Connect[i+2][j+2] |= T, B.Connect[i][j] |= T;
 70             }
 71         A.Check(), B.Check();
 72         A.Gone(), B.Gone();
 73
 74         Rep(i, 4) Ret.Connect[i][i] = 1;
 75         Rep(i, 2)
 76             Rep(j, 2) {
 77                 Ret.Connect[i][j] |= A.Connect[i][j],
 78                 Ret.Connect[i+2][j+2] |= B.Connect[i+2][j+2];
 79             }
 80         Ret.Check();
 81         Rep(k, 2)
 82             For(i, 0, 1)
 83                 For(j, 2, 3)
 84                     Ret.Connect[i][j] |= A.Connect[i][k+2]&B.Connect[k][j];
 85         Ret.Check();
 86         Ret.Gone();
 87         return Ret;
 88     }
 89 } ;
 90 struct Node {
 91     int Child[2];
 92     State Map, Barrier;
 93     //bool Con;
 94     #define C(x, y) (S[x].Child[y])
 95     #define M(x, L, R) (S[x].Map.Connect[L][R])
 96     #define B(x, L, R) (S[x].Barrier.Connect[L][R])
 97     #define Lc(x) (S[x].Child[0])
 98     #define Rc(x) (S[x].Child[1])
 99     //#define Con(x) (S[x].Con)
100 } S[N*2];
101 int Tot;
102 int n;
103 string Opt;
104
105 inline void Input() {
106     scanf("%d", &n);
107 }
108
109 inline void Build(int Left, int Right) {
110     int x = ++Tot, Mid = (Left+Right)>>1;
111     Rep(i, 4) B(x, i, i) = 1;
112     if(Left == Right) {
113         Rep(i, 4) M(x, i, i) = 1;
114         Rep(i, 2)
115             M(x, i, i+2) = M(x, i+2, i) = 1;
116         return;
117     }
118     Lc(x) = Tot+1, Build(Left, Mid);
119     Rc(x) = Tot+1, Build(Mid+1, Right);
120 }
121
122 inline void Updata(int x) {
123     S[x].Map = S[Lc(x)].Map+S[x].Barrier;
124     S[x].Map = S[x].Map+S[Rc(x)].Map;
125 }
126
127 inline void Change(int x, int Left, int Right, int G, int E) {
128     if(Left == Right) {
129         Rep(i, 4)
130             Rep(j, 4) M(x, i, j) = E;
131         Rep(i, 4) M(x, i, i) = 1;
132         Rep(i, 2)
133             M(x, i, i+2) = M(x, i+2, i) = 1;
134     } else {
135         int Mid = (Left+Right)>>1;
136         if(G <= Mid) Change(Lc(x), Left, Mid, G, E);
137         else Change(Rc(x), Mid+1, Right, G, E);
138         Updata(x);
139     }
140 }
141
142 inline void Change(int x, int Left, int Right, int L, int R, int G, int E) {
143     int Mid = (Left+Right)>>1;
144     if(R <= Mid) Change(Lc(x), Left, Mid, L, R, G, E);
145     else if(L > Mid) Change(Rc(x), Mid+1, Right, L, R, G, E);
146     else B(x, G, G+2) = B(x, G+2, G) = E;
147     Updata(x);
148 }
149
150 inline State Ask(int x, int Left, int Right, int L, int R) {
151     int Mid = (Left+Right)>>1;
152     State Ret, Temp;
153     if(Left >= L && Right <= R) Ret = S[x].Map;
154     else if(R <= Mid) Ret = Ask(Lc(x), Left, Mid, L, R);
155     else if(L > Mid) Ret = Ask(Rc(x), Mid+1, Right, L, R);
156     else {
157         Ret = Ask(Lc(x), Left, Mid, L, R);
158         Temp = Ask(Rc(x), Mid+1, Right, L, R);
159         Ret = Ret+S[x].Barrier;
160         Ret = Ret+Temp;
161         Ret.Gone();
162     }
163     return Ret;
164 }
165
166 inline void Solve() {
167     Build(1, n);
168
169     string Opt;
170     int Lx, Ly, Rx, Ry;
171     State Temp, Ret;
172     while(1) {
173         cin>>Opt;
174         if(Opt == "Exit") break;
175
176         scanf("%d%d%d%d", &Ly, &Lx, &Ry, &Rx);
177         if(Lx > Rx) swap(Lx, Rx), swap(Ly, Ry);
178         Ly--, Ry--;
179         if(Opt == "Open") {
180             if(Lx == Rx) Change(1, 1, n, Lx, 1);
181             else Change(1, 1, n, Lx, Rx, Ly, 1);
182         } else if(Opt == "Close") {
183             if(Lx == Rx) Change(1, 1, n, Lx, 0);
184             else Change(1, 1, n, Lx, Rx, Ly, 0);
185         } else {
186             clr(Ret.Connect, 0);
187             Rep(i, 4) Ret.Connect[i][i] = 1;
188
189             Temp = Ask(1, 1, n, 1, Lx);
190             Rep(i, 2)
191                 Rep(j, 2)
192                     Ret.Connect[i][j] |= Temp.Connect[i+2][j+2];
193             Temp = Ask(1, 1, n, Rx, n);
194             Rep(i, 2)
195                 Rep(j, 2)
196                     Ret.Connect[i+2][j+2] |= Temp.Connect[i][j];
197             Temp = Ask(1, 1, n, Lx, Rx);
198             Ret.Add(Temp);
199             Ret.Gone();
200
201             char Ans = Ret.Connect[Ly][Ry+2] ? ‘Y‘ : ‘N‘;
202             printf("%c\n", Ans);
203         }
204     }
205 }
206
207 int main() {
208     SetIO("1018");
209     Input();
210     Solve();
211     return 0;
212 }

时间: 2024-08-07 07:14:46

bzoj1018的相关文章

【BZOJ1018】[SHOI2008]堵塞的交通traffic 线段树

[BZOJ1018][SHOI2008]堵塞的交通traffic Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通.初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度发达的

【BZOJ1018】堵塞的交通(线段树)

[BZOJ1018]堵塞的交通(线段树) 题面 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵解决,道路才会恢复畅通.初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度 发达的世界,喜出

BZOJ1018线段树

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3489  Solved: 1168[Submit][Status][Discuss] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路. 小人国的

Bzoj1018 [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3458  Solved: 1158 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通.初来咋到

bzoj1018: [SHOI2008]堵塞的交通traffic 线段树

线段树维护每一块左上到左下.右上到右下.左上到右上.左下到右下.左上到右下.左下到右上的联通情况. #include<bits/stdc++.h> #define N 100005 #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define K l,r,k #define L l,M,P #define R M+1,r,S #define Z int l=1,int r=n,int k=1 u

[SHOI2008]堵塞的交通traffic(BZOJ1018)

Link is here 1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵

bzoj1018:[SHOI2008]堵塞的交通traffic

思路:线段树好题,用线段树维护连通性. 区间[l,r]表示左端点为l,右端点为r,宽度为2的矩形,那么线段树区间维护的就是该区间内的四个角的连通情况,注意是该区间内的连通情况,也就是说只能通过该区间内部进行连通而不能越出区间而进行连通. 一共六种连通情况:左上对右上,左上对左下,左上对右下,右上对左下,右上对右下,左下对右下. 线段树的每一个节点均维护一个域a[]用来维护该区间内的连通情况,对应下图所示 然后维护的话要注意的就是因为左儿子是[l,mid],右儿子是[mid+1,r],因为线段树叶

【bzoj1018】【SHOI2008】【堵塞的交通traffic】

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MB Submit: 2252 Solved: 711 [Submit][Status][Discuss] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状

bzoj千题计划108:bzoj1018: [SHOI2008]堵塞的交通traffic

http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 用b数组表示 节点第0/1行的最右一列是否连接了右边 来 辅助 节点的合并 查询 对两个点位于矩形的位置分4种情况讨论 两点是否联通,要考虑四种情况 (以两个位置是矩形左上角和右上角为例) 1.直接联通,线段树的节点包含了这种情况,直接判断 2. 3. 4. 后三种情况需要再查询[1,l]和[r,n