您的位置:首页 > 理论基础 > 数据结构算法

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

2016-04-08 18:39 609 查看

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

  思维要缜密啊。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=1000010;
int n;
bool U[maxn],D[maxn],M[maxn];
bool t[maxn<<2][6];
bool ret[maxn<<2][6];
void Push_up(int x){
int l=x<<1,r=l|1;
t[x][0]=(t[l][0]&&t[r][0])||(t[l][2]&&t[r][3]);
t[x][1]=(t[l][1]&&t[r][1])||(t[l][3]&&t[r][2]);
t[x][2]=(t[l][0]&&t[r][2])||(t[l][2]&&t[r][1]);
t[x][3]=(t[l][1]&&t[r][3])||(t[l][3]&&t[r][0]);
t[x][4]=t[l][4]||(t[l][0]&&t[l][1]&&t[r][4]);
t[x][5]=t[r][5]||(t[r][0]&&t[r][1]&&t[l][5]);
}

void Update(int x,int l,int r,int g){
if(l==r){
t[x][0]=U[l]||(M[l]&&D[l]&&M[l+1]);
t[x][1]=D[l]||(M[l]&&U[l]&&M[l+1]);
t[x][2]=(M[l]&&D[l])||(U[l]&&M[l+1]);
t[x][3]=(M[l]&&U[l])||(D[l]&&M[l+1]);
t[x][4]=M[l]||(M[l+1]&&U[l]&&D[l]);
t[x][5]=M[l+1]||(M[l]&&U[l]&&D[l]);
return;
}
int mid=(l+r)>>1;
if(mid>=g)Update(x<<1,l,mid,g);
else Update(x<<1|1,mid+1,r,g);
Push_up(x);
}
void Query(int x,int l,int r,int a,int b){
if(l>=a&&r<=b){
ret[x][0]=t[x][0];
ret[x][1]=t[x][1];
ret[x][2]=t[x][2];
ret[x][3]=t[x][3];
ret[x][4]=t[x][4];
ret[x][5]=t[x][5];
return;
}
int mid=(l+r)>>1;
if(mid>=a)Query(x<<1,l,mid,a,b);
if(mid<b)Query(x<<1|1,mid+1,r,a,b);
if(mid>=a&&mid<b){
int ls=x<<1,rs=ls|1;
ret[x][0]=(ret[ls][0]&&ret[rs][0])||(ret[ls][2]&&ret[rs][3]);
ret[x][1]=(ret[ls][1]&&ret[rs][1])||(ret[ls][3]&&ret[rs][2]);
ret[x][2]=(ret[ls][0]&&ret[rs][2])||(ret[ls][2]&&ret[rs][1]);
ret[x][3]=(ret[ls][1]&&ret[rs][3])||(ret[ls][3]&&ret[rs][0]);
ret[x][4]=ret[ls][4]||(ret[ls][0]&&ret[ls][1]&&ret[rs][4]);
ret[x][5]=ret[rs][5]||(ret[rs][0]&&ret[rs][1]&&ret[ls][5]);
}
else{
if(mid>=a){
ret[x][0]=ret[x<<1][0];
ret[x][1]=ret[x<<1][1];
ret[x][2]=ret[x<<1][2];
ret[x][3]=ret[x<<1][3];
ret[x][4]=ret[x<<1][4];
ret[x][5]=ret[x<<1][5];
}
else{
ret[x][0]=ret[x<<1|1][0];
ret[x][1]=ret[x<<1|1][1];
ret[x][2]=ret[x<<1|1][2];
ret[x][3]=ret[x<<1|1][3];
ret[x][4]=ret[x<<1|1][4];
ret[x][5]=ret[x<<1|1][5];
}
}
}
bool Solve(int x1,int y1,int x2,int y2){
if(y1==y2){
if(x1==x2)return true;
bool re=M[y1];
if(y1<=n){
Query(1,1,n,y1,n);
re|=ret[1][4];
}
if(y1>=2){
Query(1,1,n,1,y1-1);
re|=ret[1][5];
}
return re;
}
bool t1[7],t2[7],t3[7];
memset(t1,0,sizeof(t1));
memset(t3,0,sizeof(t3));
if(1<=y1-1){
Query(1,1,n,1,y1-1);
memcpy(t1,ret[1],sizeof(ret[1]));
}
Query(1,1,n,y1,y2-1);
memcpy(t2,ret[1],sizeof(ret[1]));
if(y2<=n){
Query(1,1,n,y2,n);
memcpy(t3,ret[1],sizeof(ret[1]));
}
if(x1==x2){
if(x1==1)
return t2[0]||(t1[5]&&t2[3])||(t3[4]&&t2[2])||(t1[5]&&t2[1]&&t3[4]);
else
return t2[1]||(t1[5]&&t2[2])||(t3[4]&&t2[3])||(t1[5]&&t2[0]&&t3[4]);
}
else{
if(x1==1)
return t2[2]||(t1[5]&&t2[1])||(t3[4]&&t2[0]);
else
return t2[3]||(t1[5]&&t2[0])||(t3[4]&&t2[1]);
}
}

int main(){
freopen("traffic.in","r",stdin);
freopen("traffic.out","w",stdout);
int x1,y1,x2,y2;
char op[15];
scanf("%d",&n);n--;
while(true){
scanf("%s",op);
if(!strcmp(op,"Exit"))break;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(y1>y2){swap(x1,x2);swap(y1,y2);}
if(!strcmp(op,"Close")){
if(x1==x2)
if(x1==1)U[y1]=false;
else D[y1]=false;
else M[y1]=false;
Update(1,1,n,y1);
if(y1!=y2)Update(1,1,n,y2);
if(y1-1)Update(1,1,n,y1-1);
}
else if(!strcmp(op,"Open")){
if(x1==x2)
if(x1==1)
U[y1]=true;
else
D[y1]=true;
else
M[y1]=true;
Update(1,1,n,y1);
if(y1!=y2)Update(1,1,n,y2);
if(y1-1)Update(1,1,n,y1-1);
}
else if(!strcmp(op,"Ask"))
printf("%c\n",Solve(x1,y1,x2,y2)?'Y':'N');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: