bzoj1018 [SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic
Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 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
Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
Sample Output
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 }