[SHOI2008]堵塞的交通
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”作为
结束。我们假设在一开始所有的道路都是堵塞的。我们保证 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
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
N
线段树中区间[l, r]存储(1, l)、(2, l)、(1, r)、(2, r)四个点两两间的连通性,总共有6种
合并:
横向边用2个数组ru和rd保存,用于合并,对于6个连通性,一一合并
修改:
修改横向边时,修改ru和rd数组,然后从下往上合并
修改纵向边时,修改该区间内四种状态,然后从下往上合并
查询:
优于可能存在这样的情况:
所以[1,c1],[c1,c2],[c2,n]的连通情况都要算出来
然后根据r1,r2判断就行了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 struct Data 8 { 9 bool luru,lurd,luld,ldru,ldrd,rurd; 10 }c[400001]; 11 bool ru[200001],rd[200001]; 12 int n; 13 char s[21]; 14 Data merge(Data dl,Data dr,int mid) 15 { 16 Data dm; 17 dm.luru=(dl.luru&ru[mid]&dr.luru)||(dl.lurd&rd[mid]&dr.ldru); 18 dm.lurd=(dl.luru&ru[mid]&dr.lurd)||(dl.lurd&rd[mid]&dr.ldrd); 19 dm.luld=(dl.luld)||(ru[mid]&&rd[mid]&&dl.luru&&dl.ldrd&&dr.luld); 20 dm.ldru=(dl.ldru&&ru[mid]&&dr.luru)||(dl.ldrd&&rd[mid]&&dr.ldru); 21 dm.ldrd=(dl.ldrd&&rd[mid]&&dr.ldrd)||(dl.ldru&&ru[mid]&&dr.lurd); 22 dm.rurd=(dr.rurd)||(ru[mid]&&rd[mid]&&dr.luru&&dr.ldrd&&dl.rurd); 23 return dm; 24 } 25 void update1(int rt,int l,int r,int x,bool up,bool k) 26 { 27 if (l==r) 28 { 29 if (up) ru[x]=k; 30 else rd[x]=k; 31 return; 32 } 33 int mid=(l+r)>>1; 34 if (x<=mid) update1(rt<<1,l,mid,x,up,k); 35 else update1(rt<<1|1,mid+1,r,x,up,k); 36 c[rt]=merge(c[rt<<1],c[rt<<1|1],mid); 37 } 38 void update2(int rt,int l,int r,int x,bool k) 39 { 40 if (l==r) 41 { 42 c[rt].luld=c[rt].rurd=c[rt].lurd=c[rt].ldru=k; 43 return; 44 } 45 int mid=(l+r)>>1; 46 if (x<=mid) update2(rt<<1,l,mid,x,k); 47 else update2(rt<<1|1,mid+1,r,x,k); 48 c[rt]=merge(c[rt<<1],c[rt<<1|1],mid); 49 } 50 Data query(int rt,int l,int r,int L,int R) 51 { 52 if (l==L&&r==R) 53 { 54 return c[rt]; 55 } 56 int mid=(l+r)>>1; 57 if (L>mid) return query(rt<<1|1,mid+1,r,L,R); 58 else if (R<=mid) return query(rt<<1,l,mid,L,R); 59 else 60 { 61 return merge(query(rt<<1,l,mid,L,mid),query(rt<<1|1,mid+1,r,mid+1,R),mid); 62 } 63 } 64 void build(int rt,int l,int r) 65 { 66 if (l==r) 67 { 68 c[rt].luru=1;c[rt].ldrd=1; 69 return; 70 } 71 int mid=(l+r)>>1; 72 build(rt<<1,l,mid); 73 build(rt<<1|1,mid+1,r); 74 } 75 int main() 76 {int i,r1,r2,c1,c2; 77 cin>>n; 78 build(1,1,n); 79 for (i=1;i<n;i++) 80 ru[i]=rd[i]=0; 81 while (1) 82 { 83 scanf("%s",s); 84 scanf("%d%d%d%d",&r1,&c1,&r2,&c2); 85 if (c1>c2) swap(c1,c2),swap(r1,r2); 86 if (s[0]=='E') break; 87 if (s[0]=='O') 88 { 89 if (r1==r2) 90 update1(1,1,n,c1,r1==1,1); 91 else update2(1,1,n,c2,1); 92 } 93 else if (s[0]=='C') 94 { 95 if (r1==r2) 96 update1(1,1,n,c1,r1==1,0); 97 else update2(1,1,n,c2,0); 98 } 99 else 100 { 101 Data dm=query(1,1,n,c1,c2),dl=query(1,1,n,1,c1),dr=query(1,1,n,c2,n); 102 if (r1==1&&r2==1) 103 { 104 bool b1=dm.luru; 105 bool b2=dl.rurd&dm.ldru; 106 bool b3=dm.lurd&dr.luld; 107 bool b4=dl.rurd&dm.ldrd&dr.luld; 108 if (b1||b2||b3||b4) printf("Y\n"); 109 else printf("N\n"); 110 } 111 else if (r1==2&&r2==2) 112 { 113 bool b1=dm.ldrd; 114 bool b2=dl.rurd&dm.lurd; 115 bool b3=dm.ldru&dr.luld; 116 bool b4=dl.rurd&dm.luru&dr.luld; 117 if (b1||b2||b3||b4) printf("Y\n"); 118 else printf("N\n"); 119 } 120 else if (r1==1&&r2==2) 121 { 122 bool b1=dm.lurd; 123 bool b2=dl.rurd&dm.ldrd; 124 bool b3=dm.luru&dr.luld; 125 bool b4=dl.rurd&dm.ldru&dr.luld; 126 if (b1||b2||b3||b4) printf("Y\n"); 127 else printf("N\n"); 128 } 129 else if (r1==2&&r2==1) 130 { 131 bool b1=dm.ldru; 132 bool b2=dl.rurd&dm.luru; 133 bool b3=dm.ldrd&dr.luld; 134 bool b4=dl.rurd&dm.lurd&dr.luld; 135 if (b1||b2||b3||b4) printf("Y\n"); 136 else printf("N\n"); 137 } 138 } 139 } 140 }