【bzoj1018】[SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic
Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2887 Solved: 954
[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”作为
结束。我们假设在一开始所有的道路都是堵塞的。我们保证 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
一道很恶心的线段树维护区间连通性(蒟蒻这才知道线段树可以干这个),不知道怎么维护的看我代码。
注意细节,整整调试了1天才A掉。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<ctime> 7 #include<algorithm> 8 using namespace std; 9 const int MAXN=100010; 10 struct node 11 { 12 bool luru,lurd,luld,rurd,ldru,ldrd; 13 }tr[MAXN*4]; 14 char ch[10]; 15 int n,k,v,limleft,limright,toright[2][MAXN]; 16 inline int read() 17 { 18 int x=0,f=1; char ch=getchar(); 19 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} 20 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} 21 return x*f; 22 } 23 void build(int p,int l,int r) 24 { 25 if(l>r) return; 26 if(l==r) 27 { 28 tr[p].luru=tr[p].ldrd=1; 29 return; 30 } 31 int mid=(l+r)/2; 32 build(p*2,l,mid); 33 build(p*2+1,mid+1,r); 34 } 35 node merge(node a,node b,int upedge,int downedge) 36 { 37 node c; 38 c.luld=a.luld; c.rurd=b.rurd; 39 c.luru=(a.luru&upedge&b.luru)|(a.lurd&downedge&b.ldru); 40 c.ldrd=(a.ldrd&downedge&b.ldrd)|(a.ldru&upedge&b.lurd); 41 c.lurd=(c.luru&c.rurd)|(c.luld&c.ldrd)|(a.luru&upedge&b.lurd)|(a.lurd&downedge&b.ldrd); 42 c.ldru=(c.luld&c.luru)|(c.ldrd&c.rurd)|(a.ldru&upedge&b.luru)|(a.ldrd&downedge&b.ldru); 43 c.luld=c.luld|(c.lurd&c.ldrd)|(c.ldru&c.luru)|(a.luru&upedge&b.luld&downedge&a.ldrd); 44 c.rurd=c.rurd|(c.lurd&c.luru)|(c.ldru&c.ldrd)|(b.luru&upedge&a.rurd&downedge&b.ldrd); 45 return c; 46 } 47 void updata1(int p,int l,int r) 48 { 49 if(l>k||r<k) return; 50 if(l==k&&r==k) 51 { 52 tr[p].luld=tr[p].rurd=tr[p].lurd=tr[p].ldru=v; 53 return; 54 } 55 int mid=(l+r)/2; 56 updata1(p*2,l,mid); 57 updata1(p*2+1,mid+1,r); 58 tr[p]=merge(tr[p*2],tr[p*2+1],toright[0][mid],toright[1][mid]); 59 } 60 void updata2(int p,int l,int r) 61 { 62 if(l>k||r<k) return; 63 if(l==k&&r==k) return; 64 int mid=(l+r)/2; 65 updata2(p*2,l,mid); 66 updata2(p*2+1,mid+1,r); 67 tr[p]=merge(tr[p*2],tr[p*2+1],toright[0][mid],toright[1][mid]); 68 } 69 node get(int p,int l,int r) 70 { 71 node a,b,c; 72 if(l>=limleft&&r<=limright) return tr[p]; 73 int mid=(l+r)/2; 74 if(mid+1<=limleft) return get(p*2+1,mid+1,r); 75 else if(limright<=mid) return get(p*2,l,mid); 76 else 77 { 78 a=get(p*2,l,mid); 79 b=get(p*2+1,mid+1,r); 80 c=merge(a,b,toright[0][mid],toright[1][mid]); 81 } 82 return c; 83 } 84 int main() 85 { 86 //freopen("bzoj_1018.in","r",stdin); 87 //freopen("bzoj_1018.out","w",stdout); 88 n=read(); 89 build(1,1,n); 90 while(scanf("%s",ch+1)) 91 { 92 if(ch[1]=='E') break; 93 if(ch[1]=='O') 94 { 95 int x1=read(),y1=read(),x2=read(),y2=read(); 96 if(y1==y2&&x1!=x2) 97 { 98 k=y1; v=1; 99 updata1(1,1,n); 100 } 101 if(x1==x2&&y1!=y2) 102 { 103 y1=min(y1,y2); k=y1; 104 toright[x1-1][y1]=1; updata2(1,1,n); 105 } 106 } 107 if(ch[1]=='C') 108 { 109 int x1=read(),y1=read(),x2=read(),y2=read(); 110 if(y1>y2) {swap(x1,x2); swap(y1,y2);} 111 if(y1==y2&&x1!=x2) 112 { 113 k=y1; v=0; 114 updata1(1,1,n); 115 } 116 if(x1==x2&&y1!=y2) 117 { 118 y1=min(y1,y2); k=y1; 119 toright[x1-1][y1]=0; updata2(1,1,n); 120 } 121 } 122 if(ch[1]=='A') 123 { 124 int x1=read(),y1=read(),x2=read(),y2=read(); 125 if(x1==x2&&y1==y2) printf("Y\n"); 126 if(y1>y2) {swap(x1,x2); swap(y1,y2);} 127 limleft=1; limright=y1; node Left=get(1,1,n); 128 limleft=y1; limright=y2; node Mid=get(1,1,n); 129 limleft=y2; limright=n; node Right=get(1,1,n); 130 if(y1==y2&&x1!=x2) 131 { 132 if(Left.rurd||Mid.luld||Right.luld) printf("Y\n"); 133 else printf("N\n"); 134 } 135 if(x1==x2&&y1!=y2) 136 { 137 if(x1==1) 138 { 139 if((Left.rurd&&Mid.ldrd&&Right.luld)||Mid.luru||(Left.rurd&&Mid.ldru)||(Mid.lurd&&Right.luld)) printf("Y\n"); 140 else printf("N\n"); 141 } 142 else 143 { 144 if((Left.rurd&&Mid.luru&&Right.luld)||Mid.ldrd||(Left.rurd&&Mid.lurd)||(Mid.ldru&&Right.luld)) printf("Y\n"); 145 else printf("N\n"); 146 } 147 } 148 if(x1!=x2&&y1!=y2) 149 { 150 if(x1==1) 151 { 152 if((Left.rurd&&Mid.ldru&&Right.luld)||Mid.lurd||(Left.rurd&&Mid.ldrd)||(Mid.luru&&Right.luld)) printf("Y\n"); 153 else printf("N\n"); 154 } 155 else 156 { 157 if((Left.rurd&&Mid.lurd&&Right.luld)||Mid.ldru||(Left.rurd&&Mid.luru)||(Mid.ldrd&&Right.luld)) printf("Y\n"); 158 else printf("N\n"); 159 } 160 } 161 } 162 } 163 return 0; 164 }