【bzoj1018】[SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit: 162 MB
Submit: 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

Sample Output

Y
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 }

 

 
 
 
 
posted @ 2016-09-22 12:50  chty  阅读(248)  评论(0编辑  收藏  举报