[SHOI2008]堵塞的交通

题目描述

有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可
以被看成是一个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;

输入格式

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

输出格式

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

输入输出样例

输入样例#1:

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

输出样例#1:

Y
N


这题真TM恶心

线段树维护区间的连通性

需要维护以下的量

(设A,B,C,D是一段区间的左上端点,右上端点,左下端点,右下端点)

upp 区间的中间两列在第1行是否连通

dow 区间的中间两列在第2行是否连通

\(A B\)
\(C D\)
l A -> C 是否连通
r B -> D 是否连通
u A -> B 是否连通
d C -> D 是否连通
ud A -> D 是否连通
du B -> C 是否连通
然后区间合并肥肠恶心
一开始自己瞎写姿势不是很对一直30
之后对着题解改了半天发现跟题解差不多了==

#include<cstdio>
#include<algorithm>
const int M = 100005 ;
using namespace std ;
inline int read() { 
    char c = getchar() ; int x = 0 , w = 1 ;
    while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
    while(c>='0'&&c<='9') { x = x*10+c - '0'; c = getchar() ; }
    return x*w ;
}
# define ls now<<1
# define rs now<<1|1
struct Node {
	bool upp , dow ;
	bool l , r , u , d , ud , du ;
}t[M<<2] ;
inline void pushup(Node &t , Node tl , Node tr) {
	t.l = tl.l | (tl.u & t.upp & tr.l & t.dow & tl.d) ;
	t.r = tr.r | (tr.u & t.upp & tl.r & t.dow & tr.d) ;
	t.u = (tl.u & t.upp & tr.u) | (tl.ud & t.dow & tr.du) ;
	t.d = (tl.d & t.dow & tr.d) | (tl.du & t.upp & tr.ud) ;
    t.ud = (tl.u & t.upp & tr.ud) | (tl.ud & t.dow & tr.d) ;
    t.du = (tl.d & t.dow & tr.du) | (tl.du & t.upp & tr.u) ;
}
void Build(int l , int r , int now) {
	if(l == r) {
		t[now].upp = t[now].dow = t[now].u = t[now].d = 1 ;
		return ;
	}
	int mid = (l + r)>>1 ;
	Build(l , mid , ls) ; Build(mid + 1 , r , rs) ;
}
void Changeh(int x , int h , int val , int l , int r , int now) {
	int mid = (l + r)>>1 ;
	if(mid == x) {
		if(h == 1) t[now].upp = val ;
		else t[now].dow = val ;
		pushup(t[now] , t[ls] , t[rs]) ;
		return ;
	}
	if(mid >= x) Changeh(x , h , val , l , mid , ls) ;
	else Changeh(x , h , val , mid + 1 , r , rs) ;
	pushup(t[now] , t[ls] , t[rs]) ;
}
void Changel(int x , int val , int l , int r , int now) {
	if(l == r) {
		t[now].l = t[now].r = t[now].ud = t[now].du = val ;
		return ;
	}
	int mid = (l + r)>>1 ;
	if(mid >= x) Changel(x , val , l , mid , ls) ;
	else Changel(x , val , mid + 1 , r , rs) ;
	pushup(t[now] , t[ls] , t[rs]) ;
}
Node query(int L , int R , int l , int r , int now) {
	if(l >= L && r <= R) return t[now] ;
	int mid = (l + r)>>1 ;
	if(mid >= R) return query(L , R , l , mid , ls) ;
	else if(mid < L) return query(L , R , mid + 1 , r , rs) ;
	else {
		Node temp = t[now] ;
		pushup(temp , query(L , mid , l , mid , ls) , query(mid + 1 , R , mid + 1 , r , rs)) ;
	    return temp ;
	}
}
int main() {
	int n = read() ; Build(1 , n , 1) ;
	char s[15] ; int r1 , r2 , c1 , c2 ;
	scanf("%s",s) ;
	while(s[0] != 'E') {
		r1 = read() , c1 = read() , r2 = read() , c2 = read() ;
		if(c1 > c2) swap(c1 , c2) , swap(r1 , r2) ;
		if(s[0] == 'O') {
			if(r1 == r2) Changeh(c1 , r1 , 1 , 1 , n , 1) ;
			else Changel(c1 , 1 , 1 , n , 1) ;
		}
		else if(s[0] == 'C') {
			if(r1 == r2) Changeh(c1 , r1 , 0 , 1 , n , 1) ;
			else Changel(c1 , 0 , 1 , n , 1) ; 
		}
		else if(s[0] == 'A') {
			bool Ans = 0 ;
			Node l = query(1 , c1 , 1 , n , 1) , x = query(c1 , c2 , 1 , n , 1) , r = query(c2 , n , 1 , n , 1) ;
		    if(r1 == 1 && r2 == 1) Ans = x.u | (l.r & x.du) | (x.ud & r.l) | (l.r & x.d & r.l) ;
		    else if(r1 == 1 && r2 == 2) Ans = x.ud | (l.r & x.d) | (x.u & r.l) | (l.r & x.du & r.l) ;
		    else if(r1 == 2 && r2 == 1) Ans = x.du | (l.r & x.u) | (x.d & r.l) | (l.r & x.ud & r.l) ;
		    else if(r1 == 2 && r2 == 2) Ans = x.d | (l.r & x.ud) | (x.du & r.l) | (l.r & x.u & r.l) ;
		    printf(Ans ? "Y\n" : "N\n") ;
		}
		scanf("%s",s) ;
	}
	return 0 ;
}
posted @ 2018-08-16 16:51  beretty  阅读(136)  评论(0编辑  收藏  举报