1018: [SHOI2008]堵塞的交通traffic
Time Limit: 3 Sec Memory Limit: 162 MB
Submit: 2638 Solved: 864
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
思维要缜密啊。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int maxn=1000010; 6 int n; 7 bool U[maxn],D[maxn],M[maxn]; 8 bool t[maxn<<2][6]; 9 bool ret[maxn<<2][6]; 10 void Push_up(int x){ 11 int l=x<<1,r=l|1; 12 t[x][0]=(t[l][0]&&t[r][0])||(t[l][2]&&t[r][3]); 13 t[x][1]=(t[l][1]&&t[r][1])||(t[l][3]&&t[r][2]); 14 t[x][2]=(t[l][0]&&t[r][2])||(t[l][2]&&t[r][1]); 15 t[x][3]=(t[l][1]&&t[r][3])||(t[l][3]&&t[r][0]); 16 t[x][4]=t[l][4]||(t[l][0]&&t[l][1]&&t[r][4]); 17 t[x][5]=t[r][5]||(t[r][0]&&t[r][1]&&t[l][5]); 18 } 19 20 void Update(int x,int l,int r,int g){ 21 if(l==r){ 22 t[x][0]=U[l]||(M[l]&&D[l]&&M[l+1]); 23 t[x][1]=D[l]||(M[l]&&U[l]&&M[l+1]); 24 t[x][2]=(M[l]&&D[l])||(U[l]&&M[l+1]); 25 t[x][3]=(M[l]&&U[l])||(D[l]&&M[l+1]); 26 t[x][4]=M[l]||(M[l+1]&&U[l]&&D[l]); 27 t[x][5]=M[l+1]||(M[l]&&U[l]&&D[l]); 28 return; 29 } 30 int mid=(l+r)>>1; 31 if(mid>=g)Update(x<<1,l,mid,g); 32 else Update(x<<1|1,mid+1,r,g); 33 Push_up(x); 34 } 35 void Query(int x,int l,int r,int a,int b){ 36 if(l>=a&&r<=b){ 37 ret[x][0]=t[x][0]; 38 ret[x][1]=t[x][1]; 39 ret[x][2]=t[x][2]; 40 ret[x][3]=t[x][3]; 41 ret[x][4]=t[x][4]; 42 ret[x][5]=t[x][5]; 43 return; 44 } 45 int mid=(l+r)>>1; 46 if(mid>=a)Query(x<<1,l,mid,a,b); 47 if(mid<b)Query(x<<1|1,mid+1,r,a,b); 48 if(mid>=a&&mid<b){ 49 int ls=x<<1,rs=ls|1; 50 ret[x][0]=(ret[ls][0]&&ret[rs][0])||(ret[ls][2]&&ret[rs][3]); 51 ret[x][1]=(ret[ls][1]&&ret[rs][1])||(ret[ls][3]&&ret[rs][2]); 52 ret[x][2]=(ret[ls][0]&&ret[rs][2])||(ret[ls][2]&&ret[rs][1]); 53 ret[x][3]=(ret[ls][1]&&ret[rs][3])||(ret[ls][3]&&ret[rs][0]); 54 ret[x][4]=ret[ls][4]||(ret[ls][0]&&ret[ls][1]&&ret[rs][4]); 55 ret[x][5]=ret[rs][5]||(ret[rs][0]&&ret[rs][1]&&ret[ls][5]); 56 } 57 else{ 58 if(mid>=a){ 59 ret[x][0]=ret[x<<1][0]; 60 ret[x][1]=ret[x<<1][1]; 61 ret[x][2]=ret[x<<1][2]; 62 ret[x][3]=ret[x<<1][3]; 63 ret[x][4]=ret[x<<1][4]; 64 ret[x][5]=ret[x<<1][5]; 65 } 66 else{ 67 ret[x][0]=ret[x<<1|1][0]; 68 ret[x][1]=ret[x<<1|1][1]; 69 ret[x][2]=ret[x<<1|1][2]; 70 ret[x][3]=ret[x<<1|1][3]; 71 ret[x][4]=ret[x<<1|1][4]; 72 ret[x][5]=ret[x<<1|1][5]; 73 } 74 } 75 } 76 bool Solve(int x1,int y1,int x2,int y2){ 77 if(y1==y2){ 78 if(x1==x2)return true; 79 bool re=M[y1]; 80 if(y1<=n){ 81 Query(1,1,n,y1,n); 82 re|=ret[1][4]; 83 } 84 if(y1>=2){ 85 Query(1,1,n,1,y1-1); 86 re|=ret[1][5]; 87 } 88 return re; 89 } 90 bool t1[7],t2[7],t3[7]; 91 memset(t1,0,sizeof(t1)); 92 memset(t3,0,sizeof(t3)); 93 if(1<=y1-1){ 94 Query(1,1,n,1,y1-1); 95 memcpy(t1,ret[1],sizeof(ret[1])); 96 } 97 Query(1,1,n,y1,y2-1); 98 memcpy(t2,ret[1],sizeof(ret[1])); 99 if(y2<=n){ 100 Query(1,1,n,y2,n); 101 memcpy(t3,ret[1],sizeof(ret[1])); 102 } 103 if(x1==x2){ 104 if(x1==1) 105 return t2[0]||(t1[5]&&t2[3])||(t3[4]&&t2[2])||(t1[5]&&t2[1]&&t3[4]); 106 else 107 return t2[1]||(t1[5]&&t2[2])||(t3[4]&&t2[3])||(t1[5]&&t2[0]&&t3[4]); 108 } 109 else{ 110 if(x1==1) 111 return t2[2]||(t1[5]&&t2[1])||(t3[4]&&t2[0]); 112 else 113 return t2[3]||(t1[5]&&t2[0])||(t3[4]&&t2[1]); 114 } 115 } 116 117 int main(){ 118 freopen("traffic.in","r",stdin); 119 freopen("traffic.out","w",stdout); 120 int x1,y1,x2,y2; 121 char op[15]; 122 scanf("%d",&n);n--; 123 while(true){ 124 scanf("%s",op); 125 if(!strcmp(op,"Exit"))break; 126 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 127 if(y1>y2){swap(x1,x2);swap(y1,y2);} 128 if(!strcmp(op,"Close")){ 129 if(x1==x2) 130 if(x1==1)U[y1]=false; 131 else D[y1]=false; 132 else M[y1]=false; 133 Update(1,1,n,y1); 134 if(y1!=y2)Update(1,1,n,y2); 135 if(y1-1)Update(1,1,n,y1-1); 136 } 137 else if(!strcmp(op,"Open")){ 138 if(x1==x2) 139 if(x1==1) 140 U[y1]=true; 141 else 142 D[y1]=true; 143 else 144 M[y1]=true; 145 Update(1,1,n,y1); 146 if(y1!=y2)Update(1,1,n,y2); 147 if(y1-1)Update(1,1,n,y1-1); 148 } 149 else if(!strcmp(op,"Ask")) 150 printf("%c\n",Solve(x1,y1,x2,y2)?‘Y‘:‘N‘); 151 } 152 return 0; 153 }