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

Link is here

1018: [SHOI2008]堵塞的交通traffic


Time Limit: 3 Sec  Memory
Limit: 162 MB

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

感觉自己太水了T_T...
先跪舔squarefk大神,祝他这次高考420+60满分虐THU...

线段树维护区间连通性的题,方神维护了一个link类{lb,rb,b[2][2]} //左边连通性,右边连通性,中间连通性(如图)

对于每个区间维护一个link类,和中点的连通性。

建树时只每个叶子的link类的b[0][0]和b[1][1]显然都是联通的(自己联通自己)

修改操作分成两种,一种是在一列的,一种是在一行的,讨论下即可。

查询操作没有什么区别。

合并操作也没有什么区别,画个图就可以写出来了,但要注意细节QAQ...

  ORZ Squarefk 跪跪跪...

以下是模仿大神的codes:

 1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<algorithm>
6 using namespace std;
7 const int N = 100010;
8 #define Ch1 (i<<1)
9 #define Ch2 (i<<1)|1
10 #define For(i,n) for(int i=1;i<=n;i++)
11 #define Rep(i,l,r) for(int i=l;i<=r;i++)
12
13 struct Link{
14 bool lb,rb,b[2][2];
15 }Left,Right,Mid;
16 struct tnode{
17 int l,r,mid;
18 bool b0,b1;Link b;
19 }T[N*4];
20 char op[10];
21 bool ans;
22 int n,x1,x2,y1,y2;
23
24 Link Merge(Link Left,Link Right,bool b0,bool b1){
25 Link merged;
26 merged.lb = Left.lb||(( Left.b[0][0])&&( Left.b[1][1])&&(b0)&&(b1)&&(Right.lb));
27 merged.rb = Right.rb||((Right.b[0][0])&&(Right.b[1][1])&&(b0)&&(b1)&&(Left.rb));
28 memset(merged.b,false,sizeof(merged.b));
29 if(b0) Rep(i,0,1)
30 Rep(j,0,1) merged.b[i][j] |= Left.b[i][0] && Right.b[0][j];
31 if(b1) Rep(i,0,1)
32 Rep(j,0,1) merged.b[i][j] |= Left.b[i][1] && Right.b[1][j];
33 return merged;
34 }
35
36 void Build(int l,int r,int i){
37 T[i].l = l; T[i].r = r; T[i].mid = (l+r)>>1;
38 if(l==r){
39 T[i].b.b[0][0] = T[i].b.b[1][1] = true;
40 return;
41 }
42 Build(l,T[i].mid,Ch1); Build(T[i].mid+1,r,Ch2);
43 }
44
45 Link query(int l,int r,int i){
46 if(l<=T[i].l&&T[i].r<=r) return T[i].b;
47 if(r<=T[i].mid) return query(l,r,Ch1);
48 if(l>T[i].mid) return query(l,r,Ch2);
49 return Merge(query(l,r,Ch1),query(l,r,Ch2),T[i].b0,T[i].b1);
50 }
51
52 void Modify(int i,bool change){
53 if((x1==x2)&&(y1==T[i].mid)){
54 if(x1) T[i].b1 = change;else T[i].b0 = change;
55 T[i].b = Merge(T[Ch1].b,T[Ch2].b,T[i].b0,T[i].b1);
56 }else if(T[i].l==T[i].r)
57 T[i].b.lb = T[i].b.rb = T[i].b.b[0][1] = T[i].b.b[1][0] = change;
58 else{
59 if(y2>T[i].mid) Modify(Ch2,change);
60 else Modify(Ch1,change);
61 T[i].b = Merge(T[Ch1].b,T[Ch2].b,T[i].b0,T[i].b1);
62 }
63 }
64
65 int main(){
66 scanf("%d",&n);
67 Build(1,n,1);
68 for(;;){
69 scanf("%s",op);
70 if(!strcmp("Exit",op)) return 0;
71 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);x1--;x2--;
72 if(y1>y2) swap(y1,y2),swap(x1,x2);
73 if(!strcmp("Open",op)) Modify(1,true);
74 if(!strcmp("Close",op)) Modify(1,false);
75 if(!strcmp("Ask",op)){
76 Left = query(1,y1,1);
77 Right = query(y2,n,1);
78 Mid = query(y1,y2,1);
79 bool ans = false;
80 Rep(i,0,1)
81 Rep(j,0,1)
82 if(Mid.b[i][j])
83 if((i==x1||Left.rb)&&(j==x2||Right.lb)) ans = true;
84 if(ans) puts("Y");else puts("N");
85 }
86 }
87 return 0;
88 }

跪跪跪

 

时间: 2024-10-05 05:11:59

[SHOI2008]堵塞的交通traffic(BZOJ1018)的相关文章

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

[BZOJ1018][SHOI2008]堵塞的交通traffic 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

BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]

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

数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic

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

【BZOJ 1018】 [SHOI2008]堵塞的交通traffic

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

1018: [SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic 链接 分析: 用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可. 六种情况左上到右上(左边到右边的情况)……,左上到左下(同一侧相互到达的情况)…… 同一侧相互到达的情况,查询[l,r]是查的不完全.因为还有可能是先往左边走几步,下去,在走回来.这时候,查询一下[1,l]的情况,或起来即可. 代码: 1 #include<cstdio> 2 #include<algorithm> 3 #i

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

bzoj1018:[SHOI2008]堵塞的交通traffic

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