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

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 }

 

posted @ 2016-04-08 18:39  TenderRun  阅读(...)  评论(... 编辑 收藏