数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic
2016-04-08 18:39
609 查看
1018: [SHOI2008]堵塞的交通traffic
Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 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
2Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
Sample Output
YN
思维要缜密啊。
#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; }
相关文章推荐
- 数据结构实用概念
- 【学习笔记----数据结构07-队列】
- 【学习笔记----数据结构06-栈的应用】
- 数据结构-堆
- 【学习笔记----数据结构05-栈与队列】
- 【学习笔记----数据结构04-单循环链表】
- 位运算-Number of 1 Bits(求一个十进制数字,它的二进制表示中有多少个 1(bit))
- 【学习笔记----数据结构03--线性链表】
- 数组分段查找
- 栈-Min Stack(实现一个栈,用常数级时间找出栈中的最小值)
- 【学习笔记----数据结构01-概述】
- hdu 1506(dp || 单调栈)
- 常用数据结构及类
- HashMap源码注解 之 内部数据结构 Node (三)
- 1、Linux驱动重要的数据结构
- 数据结构学习(1)
- 【学习笔记----数据结构02--线性表】
- SDUT 2116----数据结构实验之链表一:顺序建立链表
- 数据结构与算法——AVL树类的C++实现
- mysql 中decimal数据结构