BZOJ 1018 堵塞的交通
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
Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
Sample Output
N
HINT
Source
一道很恶心的数据结构题,但是数据结构却很简单,就是一颗裸的线段树。然而,用线段树维护连通性却很恶心(因为它只有相邻的两个点之间有连边)。我的线段树维护了8个域——左右,上下,对角,中间。慢慢写,反正我是写醉了。
奉劝:(代码仅限对拍,莫看莫看)
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std; #define maxn 100010
int n;
struct node
{
int lc,rc,l,r;
bool u[]; //左上-左下 右上-右下
bool v[]; //左上-右上 左下-右下
bool w[]; //左下-右上 左上-右下
bool t[]; //中间的两个
};
struct SEG
{
int cnt; node tree[maxn*]; inline void updata(int now,bool flag)
{
tree[now].w[] = tree[now].w[] = false;
if (!flag) if (tree[now].l != tree[now].r) tree[now].u[] = tree[now].u[] = false,tree[now].v[] = tree[now].v[] = false;
int lc = tree[now].lc,rc = tree[now].rc; bool sign = false;
do
{
sign = false;
if (!tree[now].u[])
{
if (tree[now].v[]&&tree[now].w[])
tree[now].u[] = true,sign = true;
else if (tree[now].v[]&&tree[now].w[])
tree[now].u[] = true,sign = true;
else if (tree[now].u[]&&tree[now].v[]&&tree[now].v[])
tree[now].u[] = true,sign = true;
else if (tree[lc].u[]) tree[now].u[] = true,sign = true;
}
if (!tree[now].u[])
{
if (tree[now].v[]&&tree[now].w[])
tree[now].u[] = true,sign = true;
else if (tree[now].v[]&&tree[now].w[])
tree[now].u[] = true,sign = true;
else if (tree[now].u[]&&tree[now].v[]&&tree[now].v[])
tree[now].u[] = true,sign = true;
else if (tree[rc].u[]) tree[now].u[] = true,sign = true;
}
if (!tree[now].v[])
{
if (tree[now].r - tree[now].l == && tree[now].t[])
tree[now].v[] = true,sign = true;
else if (tree[now].u[]&&tree[now].w[])
tree[now].v[] = true,sign = true;
else if (tree[now].u[]&&tree[now].w[])
tree[now].v[] = true,sign = true;
else if (tree[lc].v[]&&tree[rc].v[]&&tree[now].t[])
tree[now].v[] = true,sign = true;
else if (tree[lc].w[]&&tree[now].t[]&&tree[rc].w[])
tree[now].v[] = true,sign = true;
}
if (!tree[now].v[])
{
if (tree[now].r - tree[now].l == && tree[now].t[])
tree[now].v[] = true,sign = true;
if (tree[now].u[]&&tree[now].w[])
tree[now].v[] = true,sign = true;
else if (tree[now].u[]&&tree[now].w[])
tree[now].v[] = true,sign = true;
else if (tree[lc].v[]&&tree[rc].v[]&&tree[now].t[])
tree[now].v[] = true,sign = true;
else if (tree[lc].w[]&&tree[now].t[]&&tree[rc].w[])
tree[now].v[] = true,sign = true;
}
if (!tree[now].w[])
{
if (tree[now].u[]&&tree[now].v[])
tree[now].w[] = true,sign = true;
else if (tree[now].u[]&&tree[now].v[])
tree[now].w[] = true,sign = true;
else if (tree[lc].w[]&&tree[now].t[]&&tree[rc].v[])
tree[now].w[] = true,sign = true;
else if (tree[lc].v[]&&tree[now].t[]&&tree[now].w[])
tree[now].w[] = true,sign = true;
}
if (!tree[now].w[])
{
if (tree[now].u[]&&tree[now].v[])
tree[now].w[] = true,sign = true;
else if (tree[now].u[]&&tree[now].v[])
tree[now].w[] = true,sign = true;
else if (tree[lc].w[]&&tree[now].t[]&&tree[rc].v[])
tree[now].w[] = true,sign = true;
else if (tree[lc].v[]&&tree[now].t[]&&tree[rc].w[])
tree[now].w[] = true,sign = true;
}
}
while (sign);
if (tree[now].l == tree[now].r)
tree[now].w[] = tree[now].w[] = false;
} inline int build(int l,int r)
{
int now = ++cnt,mid = (l + r) >> ;
tree[now].l = l; tree[now].r = r;
if (l == r)
{
tree[now].v[] = tree[now].v[] = true;
updata(now,);
return now;
}
tree[now].lc = build(l,mid);
tree[now].rc = build(mid+,r);
updata(now,);
return now;
} inline bool ask(int a1,int b1,int a2,int b2,int now)
{
if (a1 == a2 && b1 == b2) return true;
int l = tree[now].l,r = tree[now].r,lc = tree[now].lc,rc = tree[now].rc,mid = (l + r) >> ;
if (b1 == l&&b2 == r)
{
if (a1 == a2 && tree[now].v[a1]) return true;
if (a1 != a2)
{
if (a1 == && tree[now].w[]) return true;
if (a1 == && tree[now].w[]) return true;
if (l == r && tree[now].u[]) return true;
}
}
else if (b2 <= mid && ask(a1,b1,a2,b2,lc)) return true;
else if (b1 > mid && ask(a1,b1,a2,b2,rc)) return true;
else if (mid >= b1 && mid < b2 && tree[now].t[]&&ask(a1,b1,,mid,lc)&&ask(,mid+,a2,b2,rc)) return true;
else if (mid >= b1 && mid < b2 && tree[now].t[]&&ask(a1,b1,,mid,lc)&&ask(,mid+,a2,b2,rc)) return true;
else if (a1 != a2 && tree[now].t[] && tree[now].t[])
{
if (b2 <= mid) return tree[rc].u[]&&ask(a1,b1,a1,mid,lc)&&ask(a2,b2,a2,mid,lc);
else if (b1 > mid) return tree[lc].u[]&&ask(a1,mid+,a1,b1,rc)&&ask(a2,mid+,a2,b2,rc);
}
else if (a1 == a2 && tree[now].t[]&&tree[now].t[])
{
if (b2 <= mid)
return tree[rc].u[]&&ask(a1,b1,((a1-)^)+,b1,lc)&&ask(((a1-)^)+,b1,((a1-)^)+,mid,lc)&&ask(a2,b2,a2,mid,lc);
else if (b1 > mid)
return tree[lc].u[]&&ask(a1,b2,((a1-)^)+,b2,rc)&&ask(((a1-)^)+,mid+,((a1-)^)+,b2,rc)&&ask(a2,mid+,a2,b1,rc);
}
return false;
} inline void modify(int a1,int b1,int a2,int b2,int now,bool sign)
{
int l = tree[now].l,r = tree[now].r,lc = tree[now].lc,rc = tree[now].rc,mid = (l + r) >> ;
bool flag = false;
if (a1 == a2) //处在同一行上
{
if (b1 == mid && b2 == mid + )
tree[now].t[a1] = sign,flag = sign;
else if (b1 <= mid) modify(a1,b1,a2,b2,lc,sign);
else modify(a1,b1,a2,b2,rc,sign);
}
else //处在同一列上
{
if (l == r) tree[now].u[] = tree[now].u[] = sign,flag = true;
else if (b1 <= mid) modify(a1,b1,a2,b2,lc,sign);
else modify(a1,b1,a2,b2,rc,sign);
}
updata(now,flag|sign);
return;
}
}seg; inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-')f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=x*+ch-''; ch=getchar(); }
return x * f;
} int main()
{
freopen("1018.in","r",stdin);
freopen("1018.out","w",stdout);
n = read();
seg.build(,n);
char opt[]; int a1,a2,b1,b2;
do
{
scanf("%s ",opt);
if (opt[] == 'E') break;
a1 = read(); b1 = read(); a2 = read(); b2 = read();
if (b1 > b2) swap(a1,a2),swap(b1,b2);
if (opt[] == 'A')
{
if (seg.ask(a1,b1,a2,b2,)) printf("Y\n");
else printf("N\n");
}
else if (opt[] == 'O') seg.modify(a1,b1,a2,b2,,true);
else seg.modify(a1,b1,a2,b2,,false);
}
while (true);
return ;
}
BZOJ 1018 堵塞的交通的更多相关文章
- [BZOJ]1018 堵塞的交通(SHOI2008)
一道有点神的线段树. Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城 ...
- BZOJ 1018 堵塞的交通traffic(线段树)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1018 题意:一个2*n的格子,相邻格子之间有一条道路.初始时道路是不通的. 三种操作:( ...
- 【BZOJ】【1018】【SHOI2008】堵塞的交通traffic
线段树 这题的线段树+分类讨论蛮神奇的……我以前学的线段树简直就是渣渣QAQ 看了下ydc题解里的思想>_>用线段树维护连通性!那么就自己写吧……每个节点表示一段区间的连通性(我的叶子节点 ...
- 数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2638 Solved: 864 Descri ...
- BZOJ 1018 [SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2247 Solved: 706[Submit ...
- BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 3064 Solved: 1027[Submi ...
- [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】
题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...
- bzoj千题计划108:bzoj1018: [SHOI2008]堵塞的交通traffic
http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 ...
- 1018: [SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic 链接 分析: 用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可. 六种情况左上到右上(左边到右边的情况)… ...
随机推荐
- web.xml(7)_mime-mapping、welcome-file-list、error-page
10.mime-mapping:mime-mapping包括两个子元素extension和mime-type.定义某一个扩展名和某一MIME Type做对映. MIME(Multipurpose In ...
- TraceGL监控Node.js应用或者浏览器JavaScript代码
https://github.com/traceglMPL/tracegl TraceGL能够监控Node.js应用或者浏览器JavaScript代码的运行过程和细节.可视化的用户界面也很友好
- MapReduce实战:查找相同字母组成的单词
1.项目需求 一本英文书籍包含成千上万个单词,现在我们需要在大量的单词中,找出相同字母组成的所有单词 2.数据集 下面是一本英文书籍截取的一部分单词内容(书籍内容是随意写的,主要目的是实现这种需求) ...
- Gitolite轻松部署/管理git server
对于今天越来越受欢迎的Git,相信做开发的朋友都基本有所耳闻.它最大的便利就是分布式的开发库,让使用git作为源码管理库的开发者可以在本地提交代码的修改而不用提交到远程的库,同时需要和团队协作.同步代 ...
- 【bzoj2938】[Poi2000]病毒
题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...
- hadoop集群环境搭建之zookeeper集群的安装部署
关于hadoop集群搭建有一些准备工作要做,具体请参照hadoop集群环境搭建准备工作 (我成功的按照这个步骤部署成功了,经实际验证,该方法可行) 一.安装zookeeper 1 将zookeeper ...
- JQuery的$命名冲突详细解析
在Jquery中,$是JQuery的别名,所有使用$的地方也都可以使用JQuery来替换,如$('#msg')等同于JQuery('#msg')的写法.然而,当我们引入多个js库后,在另外一个js库中 ...
- transition的四个属性
transition-property 规定设置过渡效果的 CSS 属性的名称. transition-duration 规定完成过渡效果需要多少秒或毫秒. transition-timing-fun ...
- WinForm中的事件触发机制学习
在一个Form窗体中拖个按钮,双击后系统自动生成代码: private void button1_Click(object sender, EventArgs e) { } 同时在窗体的Initial ...
- html multiple select option 分组
普通html方式展示<select name="viewType" style="width: 100%;height: 300px;" multiple ...