标签:
[BZOJ1018][SHOI2008]堵塞的交通traffic
试题描述
输入
输出
输入示例
2 Open 1 1 1 2 Open 1 2 2 2 Ask 1 1 2 2 Ask 2 1 2 2 Exit
输出示例
Y
N
数据规模及约定
见“输入”
题解
用线段树维护连通性。每个区间维护 左上右上、左上右下、左上左下、左下右上、左下右下、右上右下 的连通性,合并两个区间时分类讨论一下怎么从起点走到目标位置。
以下代码 0, 1, 2, 3 分别表示 左上、右上、左下、右下。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 100010
#define maxlog 50
int n, maxo;
char tp[10];
bool Oc[2][maxn], Or[maxn];
bool con[4][4][maxn<<2];
void combine(int o, int lc, int rc, int M) {
con[0][1][o] = (con[0][1][lc] & Oc[0][M] & con[0][1][rc]) | (con[0][3][lc] & Oc[1][M] & con[1][2][rc]);
con[0][3][o] = (con[0][1][lc] & Oc[0][M] & con[0][3][rc]) | (con[0][3][lc] & Oc[1][M] & con[2][3][rc]);
con[0][2][o] = con[0][2][lc] | (con[0][1][lc] & Oc[0][M] & con[0][2][rc] & Oc[1][M] & con[2][3][lc]);
con[1][2][o] = (con[1][2][lc] & Oc[0][M] & con[0][1][rc]) | (con[2][3][lc] & Oc[1][M] & con[1][2][rc]);
con[1][3][o] = con[1][3][rc] | (con[0][1][rc] & Oc[0][M] & con[1][3][lc] & Oc[1][M] & con[2][3][rc]);
con[2][3][o] = (con[1][2][lc] & Oc[0][M] & con[0][3][rc]) | (con[2][3][lc] & Oc[1][M] & con[2][3][rc]);
return ;
}
void build(int L, int R, int o) {
maxo = max(maxo, o);
if(L == R) con[0][1][o] = con[2][3][o] = 1;
else {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
build(L, M, lc); build(M+1, R, rc);
combine(o, lc, rc, M);
}
return ;
}
void update(int tp, int L, int R, int o, int r, int c, int v) {
if(L == R) {
if(tp) con[0][2][o] = con[1][3][o] = con[0][3][o] = con[1][2][o] = Or[c] = v;
else Oc[r][c] = v;
return ;
}
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(c <= M) update(tp, L, M, lc, r, c, v);
else update(tp, M+1, R, rc, r, c, v);
combine(o, lc, rc, M);
return ;
}
int cnt, ql, qr, que[maxlog], quer[maxlog];
void Query(int L, int R, int o) {
if(ql <= L && R <= qr) {
que[++cnt] = o; quer[cnt] = R;
return ;
}
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(ql <= M) Query(L, M, lc);
if(qr > M) Query(M+1, R, rc);
return ;
}
bool query(int r1, int c1, int r2, int c2) {
if(c1 > c2) swap(r1, r2), swap(c1, c2);
bool flag[4]; memset(flag, 0, sizeof(flag));
cnt = 0; ql = 1; qr = c1;
Query(1, n, 1);
for(int i = 0; i < 4; i++)
for(int j = i+1; j < 4; j++) con[i][j][0] = con[i][j][que[1]];
for(int k = 2; k <= cnt; k++) {
combine(maxo + 1, 0, que[k], quer[k-1]);
for(int i = 0; i < 4; i++)
for(int j = i+1; j < 4; j++) con[i][j][0] = con[i][j][maxo+1];
}
if(con[1][3][0]) flag[0] = flag[2] = 1;
else {
if(!r1) flag[0] = 1;
else flag[2] = 1;
}
cnt = 0; ql = c2; qr = n;
Query(1, n, 1);
for(int i = 0; i < 4; i++)
for(int j = i+1; j < 4; j++) con[i][j][0] = con[i][j][que[1]];
for(int k = 2; k <= cnt; k++) {
combine(maxo + 1, 0, que[k], quer[k-1]);
for(int i = 0; i < 4; i++)
for(int j = i+1; j < 4; j++) con[i][j][0] = con[i][j][maxo+1];
}
if(con[0][2][0]) flag[1] = flag[3] = 1;
else {
if(!r2) flag[1] = 1;
else flag[3] = 1;
}
// printf("%d %d %d %d\n", r1, c1, r2, c2);
// printf("%d %d %d %d\n", flag[0], flag[1], flag[2], flag[3]);
cnt = 0; ql = c1; qr = c2;
Query(1, n, 1);
for(int i = 0; i < 4; i++)
for(int j = i+1; j < 4; j++) con[i][j][0] = con[i][j][que[1]];
for(int k = 2; k <= cnt; k++) {
combine(maxo + 1, 0, que[k], quer[k-1]);
for(int i = 0; i < 4; i++)
for(int j = i+1; j < 4; j++) con[i][j][0] = con[i][j][maxo+1];
}
// printf("%d %d %d %d %d\n", con[0][1][1], con[0][3][1], con[1][2][1], con[1][3][1], con[0][2][1]);
for(int i = 0; i < 4; i += 2)
for(int j = 1; j < 4; j += 2) if(flag[i] && flag[j] && con[min(i,j)][max(i,j)][0])
return 1;
return 0;
}
int main() {
scanf("%d", &n);
build(1, n, 1);
int top = 0, tot = 0;
while(scanf("%s", &tp) == 1) {
if(tp[0] == ‘E‘) break;
int r1, c1, r2, c2;
scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
r1--; r2--;
// int r1 = read() - 1, c1 = read(), r2 = read() - 1, c2 = read();
tot++;
if(tp[0] == ‘O‘) {
if(r1 == r2) update(0, 1, n, 1, r1, min(c1, c2), 1);
else update(1, 1, n, 1, r1, c1, 1);
}
if(tp[0] == ‘C‘) {
if(r1 == r2) update(0, 1, n, 1, r1, min(c1, c2), 0);
else update(1, 1, n, 1, r1, c1, 0);
}
if(tp[0] == ‘A‘) {
// if(++top == 192) printf("%d %d %d %d %d\n", r1, c1, r2, c2, tot);
if(query(r1, c1, r2, c2)) printf("Y\n");
else printf("N\n");
}
}
return 0;
}
cnbb 我都要调吐了。。。
[BZOJ1018][SHOI2008]堵塞的交通traffic
标签:
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/5801462.html