数据结构(线段树):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 }
时间: 2024-10-14 21:46:43

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

BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3064  Solved: 1027[Submit][Status][Discuss] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通

[BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经典模型. 我们线段树的一个节点表示一个区间的联通性,有 6 个 bool 值,表示这个区间的 4 个角上的点之间的联通性. 然后用两个子区间的联通性和两个子区间之间的连边情况合并出整个区间的联通性. 修改某条边时,先在边的数组中修改,然后从这条边所在的点的线段树叶子开始向上 Update . 询问两

[BZOJ 1018][SHOI2008]堵塞的交通traffic(线段树)

Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵解决,道路才会恢复畅通.初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度 发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入

BZOJ 1018 SHOI2008 堵塞的交通traffic 线段树

题目大意:给定一张2*n的网格图,多次改变某条边是否可用,多次查询某两个点是否联通 多(yi)年前的我看到这题的第一反应是:这题尼玛能做? 两个点之间的路径可能是这样的: 也可能是这样的: 甚至可能是这样的: 这题能写? 这题其实好写爆了 我们首先忽略第三种情况,假设所有对答案有贡献的边都在两个点的中间 那么我们以每一列为一个叶节点建立线段树 线段树的每个节点开一个二维数组a[2][2] 其中 a[x][y]记录当前区间的左端点的第x行和右端点的第y行是否联通 那么合并如下: 例如,a[0][0

bzoj 1018: [SHOI2008]堵塞的交通traffic

由于只有两行,对一个区间可以维护四个角上的连通性 一共6个量,满足区间可加性,用线段树维护,查询时找出3段的量,看是否满足题解上的三种情况之一. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<queue> 7 #include<algorithm> 8

1018: [SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic 链接 分析: 用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可. 六种情况左上到右上(左边到右边的情况)……,左上到左下(同一侧相互到达的情况)…… 同一侧相互到达的情况,查询[l,r]是查的不完全.因为还有可能是先往左边走几步,下去,在走回来.这时候,查询一下[1,l]的情况,或起来即可. 代码: 1 #include<cstdio> 2 #include<algorithm> 3 #i

【BZOJ】1018: [SHOI2008]堵塞的交通traffic

http://www.lydsy.com/JudgeOnline/problem.php?id=1018 题意:有2行,每行有c(c<=100000)个城市,则一共有c-1个格子,现在有q(q<=100000)个操作,操作Open和Close是将格子的四个角相邻的城市连边或删边,操作Ask是询问两个城市是否连通 #include <cstdio> #include <cstring> #include <cmath> #include <string&

【SHOI 2008】【BZOJ 1018】堵塞的交通traffic

发现很多有关区间联通问题的题线段树都可以做,不论是1列还是2列.这题的易错点在于两个端点x,y之间的可行路径不一定在区间[x,y]之间,有可能是从其他区间绕过来的,想明白这一点,区间的更新又与1列的情况基本类似,这题就很好做了. code: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mid (l+r)/2 #define lch i<

【BZOJ 1018】 [SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 1811  Solved: 580 [Submit][Status] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状况非常槽糕.有