【BZOJ1018】堵塞的交通(线段树)

题面

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

题解

毒瘤题

神题

欢迎入坑

BZOJ上有题解

我只讲线段树如何维护

对于每一个节点

维护的是一段区间

也就是一个矩形

现在我们维护的是这个矩形的四个顶点之间的两两的联通性

这个一顿分类讨论就好了

对于叶子节点,因为会直接的修改边

因此不能够只维护点的连通性

还要维护一下边,

再用边来推出点的连通性再向上递归

每一次的询问

先询问给定的区间

再询问1左端点以及右端点n

因为联通的情况无非就是

①在自己的区间内之间联通

②出去走一圈再回来

所以,又是一顿分类讨论,这里就很好解决了

细节太多了,不好细讲

边界情况仔细讨论

可以直接看代码

其中,我的代码

小写的l1,l2,r1,r2分别对应矩形左侧的两个点和右侧的两个点的连通性

L1等大写的表示的边的连通性

这题真是写死我了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 120000
#define lson (now<<1)
#define rson (now<<1|1)
#define rg register
inline int read()
{
rg int x=0,t=1;rg char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,P;
struct Node
{
bool l1l2,r1r2,l1r1,l1r2,l2r1,l2r2,L1L2,R1R2,L1R1,L2R2;
void init(){l1l2=r1r2=l1r1=l1r2=l2r1=l2r2=L1L2=R1R2=L1R1=L2R2=false;}
}t[MAX<<3];
Node Merge(Node x,Node y)
{
rg Node ret;ret.init();
ret.l1r1=(x.l1r1&y.l1r1)|(x.l1r2&y.l2r1);
ret.l2r2=(x.l2r2&y.l2r2)|(x.l2r1&y.l1r2);
ret.l1l2=(x.l1l2)|(ret.l1r1&ret.l2r2&y.r1r2);
ret.r1r2=(y.r1r2)|(ret.l1r1&ret.l2r2&x.l1l2);
ret.l1r2=(x.l1r1&y.l1r2)|(x.l1r2&y.l2r2);
ret.l2r1=(x.l2r2&y.l2r1)|(x.l2r1&y.l1r1);
return ret;
}
void Count(Node &a)
{
a.l1r1=(a.L1R1)|(a.L1L2&a.L2R2&a.R1R2);
a.l2r2=(a.L2R2)|(a.L1L2&a.L1R1&a.R1R2);
a.l1l2=(a.L1L2)|(a.L1R1&a.R1R2&a.L2R2);
a.r1r2=(a.R1R2)|(a.L1R1&a.L1L2&a.L2R2);
a.l1r2=(a.L1R1&a.R1R2)|(a.L1L2&a.L2R2);
a.l2r1=(a.L1L2&a.L1R1)|(a.L2R2&a.R1R2);
}
void Modify_C(int now,int l,int r,int pos)
{
if(l==r)
{
if(P==1)t[now].L1R1=false;
else if(P==2)t[now].L2R2=false;
else if(P==3)t[now].L1L2=false;
else if(P==4)t[now].R1R2=false;
Count(t[now]);
return;
}
rg int mid=(l+r)>>1;
if(pos<=mid)Modify_C(lson,l,mid,pos);
else Modify_C(rson,mid+1,r,pos);
t[now]=Merge(t[lson],t[rson]);
}
void Modify_O(int now,int l,int r,int pos)
{
if(l==r)
{
if(P==1)t[now].L1R1=true;
else if(P==2)t[now].L2R2=true;
else if(P==3)t[now].L1L2=true;
else if(P==4)t[now].R1R2=true;
Count(t[now]);
return;
}
rg int mid=(l+r)>>1;
if(pos<=mid)Modify_O(lson,l,mid,pos);
else Modify_O(rson,mid+1,r,pos);
t[now]=Merge(t[lson],t[rson]);
}
Node Query(int now,int l,int r,int al,int ar)
{
if(l==al&&r==ar)return t[now];
rg int mid=(l+r)>>1;
if(ar<=mid)return Query(lson,l,mid,al,ar);
if(al>mid)return Query(rson,mid+1,r,al,ar);
return Merge(Query(lson,l,mid,al,mid),Query(rson,mid+1,r,mid+1,ar));
}
int main()
{
n=read()-1;
rg char ch[20];
while(233)
{
scanf("%s",ch);if(ch[0]=='E')break;
else if(ch[0]=='O')
{
rg int r1=read(),c1=read(),r2=read(),c2=read();
if(c1>c2)swap(r1,r2),swap(c1,c2);
if(r1==r2&&r1==1)P=1,Modify_O(1,1,n,c1);
else if(r1==r2&&r1==2)P=2,Modify_O(1,1,n,c1);
else if(c1==c2){if(c1!=1){P=4,Modify_O(1,1,n,c1-1);}if(c1<=n)P=3,Modify_O(1,1,n,c1);}
}
else if(ch[0]=='C')
{
rg int r1=read(),c1=read(),r2=read(),c2=read();
if(c1>c2)swap(r1,r2),swap(c1,c2);
if(r1==r2&&r1==1)P=1,Modify_C(1,1,n,c1);
else if(r1==r2&&r1==2)P=2,Modify_C(1,1,n,c1);
else if(c1==c2){if(c1!=1){P=4,Modify_C(1,1,n,c1-1);}if(c1<=n)P=3,Modify_C(1,1,n,c1);}
}
else
{
rg int r1=read(),c1=read(),r2=read(),c2=read();
if(c1>c2)swap(r1,r2),swap(c1,c2);
if(c1==c2)
{
if(r1 ==r2)puts("Y");
else
{
rg Node x,y;x.init();y.init();
if(c1>1)(x=Query(1,1,n,1,c1-1));
if(c1<=n)(y=Query(1,1,n,c1,n));
(x.r1r2||y.l1l2)?puts("Y"):puts("N");
}
continue;
}
rg Node x,y,z;x.init();y.init();z.init();
x=Query(1,1,n,c1,c2-1);if(c1>=2)y=Query(1,1,n,1,c1-1);if(c2<=n)z=Query(1,1,n,c2,n);
if(r1==r2)
{
if(r1==1)((x.l1r1)||(y.r1r2&&(x.l2r1||(x.l2r2&&z.l1l2))))?puts("Y"):puts("N");
else((x.l2r2)||(y.r1r2&&(x.l1r2||(x.l1r1&&z.l1l2))))?puts("Y"):puts("N");
}
else
{
if(r1==1)((x.l1r2)||(y.r1r2&&x.l2r2)||(x.l1r1&&z.l1l2))?puts("Y"):puts("N");
else((x.l2r1)||(y.r1r2&&x.l1r1)||(x.l2r2&&z.l1l2))?puts("Y"):puts("N");
}
}
}
return 0;
}

【BZOJ1018】堵塞的交通(线段树)的更多相关文章

  1. BZOJ1018 堵塞的交通(线段树)

    题目很好明白,然后实现很神奇.首先如果考虑并查集的话,对于删边和加边操作我们无法同时进行.然后暴力分块的话,复杂度是O(n sqrt n) ,不是很优.于是看了题解,发现了线段树的神奇用途. 我们维护 ...

  2. BZOJ1018[SHOI2008]堵塞的交通——线段树

    题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总 ...

  3. bzoj1018/luogu4246 堵塞的交通 (线段树)

    对于一个区间四个角的点,可以用线段树记下来它们两两的联通情况 区间[l,r]通过两个子区间[l,m],[m+1,r]来更新,相当于合并[l,m],[m+1,r],用(m,m+1)这条边来合并 查询a, ...

  4. Luogu P4246 [SHOI2008]堵塞的交通(线段树+模拟)

    P4246 [SHOI2008]堵塞的交通 题意 题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个\(2\)行\(C\)列的矩形 ...

  5. BZOJ.1018.[SHOI2008]堵塞的交通(线段树维护连通性)

    题目链接 只有两行,可能的路径数不多,考虑用线段树维护各种路径的连通性. 每个节点记录luru(left_up->right_up),lurd,ldru,ldrd,luld,rurd,表示这个区 ...

  6. [HNOI2014] 道路堵塞 - 最短路,线段树

    对不起对不起,辣鸡蒟蒻又来用核弹打蚊子了 完全ignore了题目给出的最短路,手工搞出一个最短路,发现对答案没什么影响 所以干脆转化为经典问题:每次询问删掉一条边后的最短路 如果删掉的是非最短路边,那 ...

  7. [BZOJ1018]堵塞的交通traffic

    Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一 ...

  8. 【BZOJ1018】[SHOI2008]堵塞的交通traffic 线段树

    [BZOJ1018][SHOI2008]堵塞的交通traffic Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个 ...

  9. [bzoj1018][SHOI2008]堵塞的交通traffic_线段树

    bzoj-1018 SHOI-2008 堵塞的交通traffic 参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html 题目大意:有一天,由于某 ...

随机推荐

  1. S5PV210时钟,看门狗定时器

    晶振:时钟源(操作主要有两个,倍频,分频) A8的时钟源: 时钟域,每个时钟域(不同的最高频率和最低频率)管理着不同的电路模块: 不同的时钟域对应不同电路模块表 时钟电路:懂得看时钟电路(时钟源选择开 ...

  2. IDEA设置优化

    默认会开很多的功能,但是有些功能暂时用不到,于是想屏蔽掉. Duplicated Code冗余代码提示功能 先找到设置路径Settings -> Editor -> Inspections ...

  3. MYSQL EXPLAIN执行计划命令详解(支持更新中)

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 本篇是根据官网中的每个一点来翻译.举例.验证的:英语不好,所 ...

  4. ubuntu16 ftp 服务 vsftp 配置

    转载:沐心_ 地址:http://bbs.csdn.net/topics/392186116------------------------------------------------------ ...

  5. Linux目录结构及作用

    /:根目录 /bin:存放基础系统所需的最基础的命令(程序) binary 比如:ls.cp.mkdir等 功能和/usr/bin类似,这个目录中的文件都是可执行的,普通用户都可以使用的命令   /b ...

  6. 【学习笔记】Hibernate 一对一关联映射 组件映射 二级缓存 集合缓存

    啊讲道理放假这十天不到啊 感觉生活中充满了绝望 这就又开学了 好吧好吧继续学习笔记?还是什么的 一对一关联映射 这次我们仍然准备了两个表 一个是用户表Users 一个是档案表Resume 他们的关系是 ...

  7. Docker mongodb 3.4 分片 一主 一副 一仲 鉴权集群部署.

    非docker部署 为了避免过分冗余,并且在主节点挂了,还能顺利自动提升,所以加入仲裁节点 为什么要用docker部署,因为之前直接在虚拟机启动10个mongod 进程.多线程并发测试的时候,mong ...

  8. enable multi-tenancy on openstack pike

    Multi-tenancy 是openstack ironic从Ocata版本开始支持的新特性,通过network-generic-switch插件控制交换机,Ironic可以实现在不同租户间机网络隔 ...

  9. Linux socket网络编程基础 tcp和udp

    Socket TCP网络通信编程 首先,服务器端需要做以下准备工作: (1)调用socket()函数.建立socket对象,指定通信协议. (2)调用bind()函数.将创建的socket对象与当前主 ...

  10. Shell脚本——cat/EOF输出多行

    在某些场合,可能我们需要在脚本中生成一个临时文件,然后把该文件作为最终文件放入目录中.(可参考ntop.spec文件)这样有几个好处,其中之一就是临时文件不是唯一的,可以通过变量赋值,也可根据不同的判 ...