[bzoj1018][SHOI2008]堵塞的交通traffic_线段树
bzoj-1018 SHOI-2008 堵塞的交通traffic
参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html
题目大意:有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个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;
数据范围:$0\le C\le 10^5$,$1\le Number_{message} \le 10^5$。
想法:
哇哦。。。
这题真的能想出来?
我们用线段树维护一个列在$(l,r)$之间的这么$r-l+1$个方格的连通性。
维护的信息如下图:

然后如果在同一行的话同理。
现在,假设从左到右,从上到下,矩阵的四个角依次命名为$s1$,$s2$,$s3$,$s4$。
我们就维护
$U$:第一行的$mid$和$mid+1$是否连通。
$D$:第二行的$mid$和$mid+1$是否连通。
$l$:$s1$和$s3$是否连通。
$r$:$s2$和$s4$是否连通。
$u$:$s1$和$s2$是否连通。
$d$:$s3$和$s4$是否连通。
$q$:$s1$和$s4$是否连通。
$p$:$s2$和$s3$是否连通。
之后暴力维护就好了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
#define N 100010
using namespace std;
struct Node
{
bool U,D,l,r,u,d,p,q;
}a[N<<2];
inline void pushup(Node &p,Node l,Node r)
{
p.l = l.l | (l.u & p.U & r.l & p.D & l.d);
p.r = r.r | (r.u & p.U & l.r & p.D & r.d);
p.u = (l.u & p.U & r.u) | (l.q & p.D & r.p);
p.d = (l.d & p.D & r.d) | (l.p & p.U & r.q);
p.q = (l.u & p.U & r.q) | (l.q & p.D & r.d);
p.p = (l.d & p.D & r.p) | (l.p & p.U & r.u);
}
void build(int l,int r,int p)
{
if(l==r) {a[p].U=a[p].D=a[p].u=a[p].d=true; return;}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
pushup(a[p],a[ls],a[rs]);
}
void update_r(int x,int val,int opt,int l,int r,int p)
{
int mid=(l+r)>>1;
if(x==mid)
{
if(opt==1) a[p].U=val;
else a[p].D=val;
pushup(a[p],a[ls],a[rs]);
return;
}
if(x<=mid) update_r(x,val,opt,l,mid,ls);
else update_r(x,val,opt,mid+1,r,rs);
pushup(a[p],a[ls],a[rs]);
}
void update_c(int x,int val,int l,int r,int p)
{
if(l==r) {a[p].l=a[p].r=a[p].p=a[p].q=val; return;}
int mid=(l+r)>>1;
if(x<=mid) update_c(x,val,l,mid,ls);
else update_c(x,val,mid+1,r,rs);
pushup(a[p],a[ls],a[rs]);
}
Node query(int x,int y,int l,int r,int p)
{
if(x<=l && r<=y) return a[p];
int mid=(l+r)>>1;
if(y<=mid) return query(x,y,l,mid,ls);
else if(x>mid) return query(x,y,mid+1,r,rs);
else
{
Node re=a[p];
pushup(re,query(x,y,l,mid,ls),query(x,y,mid+1,r,rs));
return re;
}
}
int main()
{
int c; cin >> c ;
build(1,c,1);
char s[10];
int r1,r2,c1,c2;
while(scanf("%s",s) != EOF)
{
if(s[0] == 'E') break;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
if(c1 > c2) swap(c1,c2),swap(r1,r2);
if(s[0] == 'O')
{
if(r1 == r2) update_r(c1,1,r1,1,c,1);
else update_c(c1,1,1,c,1);
}
if(s[0] == 'C')
{
if(r1 == r2) update_r(c1,0,r1,1,c,1);
else update_c(c1,0,1,c,1);
}
if(s[0] == 'A')
{
Node l = query(1,c1,1,c,1),x = query(c1,c2,1,c,1),r = query(c1,c,1,c,1);
int ans;
// printf("%d\n",x.u ? 1 : 0);
// printf("%d\n",l.r ? 1 : 0);
// printf("%d\n",x.p ? 1 : 0);
// printf("%d\n",x.q ? 1 : 0);
// printf("%d\n",r.l ? 1 : 0);
// printf("%d\n",l.r ? 1 : 0);
// printf("%d\n",x.d ? 1 : 0);
// printf("%d\n",r.l ? 1 : 0);
if(r1==1 && r2==1)
/* puts("1"), */ans = x.u | (l.r & x.p) | (r.l & x.q) | (l.r & x.d & r.l);
if(r1==1 && r2==2)
/* puts("2"), */ans = x.q | (l.r & x.d) | (r.l & x.u) | (l.r & x.p & r.l);
if(r1==2 && r2==1)
/* puts("3"), */ans = x.p | (l.r & x.u) | (r.l & x.d) | (l.r & x.q & r.l);
if(r1==2 && r2==2)
/* puts("4"), */ans = x.d | (l.r & x.q) | (r.l & x.p) | (l.r & x.u & r.l);
puts(ans ? "Y" : "N");
}
}
return 0;
}
小结:妈的神仙题.....
[bzoj1018][SHOI2008]堵塞的交通traffic_线段树的更多相关文章
- [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MB Submit: 3795 Solved: 1253 [Sub ...
- BZOJ1018 SHOI2008堵塞的交通(线段树)
动态图的连通性当然是可以用LCT维护的.但这相当的不优美,毕竟这样做没有用到任何该图的性质,LCT自带的大常数也会使其跑得非常慢. 考虑用线段树维护区间左右端四个点之间各自的连通性(仅经过该区间内路径 ...
- Bzoj1018[SHOI2008]堵塞的交通traffic(线段树)
这题需要维护连通性,看到有连接删除,很容易直接就想LCT了.然而这题点数20w操作10w,LCT卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...
- bzoj1018[SHOI2008]堵塞的交通traffic——线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1018 巧妙的线段树.维护矩阵四个角的连通性. 考虑两个点连通的可能路径分成3部分:两点左边. ...
- 【BZOJ1018】堵塞的交通(线段树)
[BZOJ1018]堵塞的交通(线段树) 题面 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网 ...
- 【BZOJ1018】[SHOI2008]堵塞的交通traffic 线段树
[BZOJ1018][SHOI2008]堵塞的交通traffic Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个 ...
- BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 3064 Solved: 1027[Submi ...
- 【bzoj1018】[SHOI2008]堵塞的交通traffic 线段树区间合并+STL-set
题目描述 给出一张2*n的网格图,初始每条边都是不连通的.多次改变一条边的连通性或询问两个点是否连通. 输入 第一行只有一个整数C,表示网格的列数.接下来若干行,每行为一条交通信息,以单独的一行“Ex ...
- Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)
题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...
随机推荐
- 电商技术中企业数据总线ESB和注册服务管理的区别
一.概述 1.什么是ESB 就是企业数据总线的意思,他的核心功能就是兼容各种协议接口,可以将数据在各种协议之间进行流转,并且可以针对数据格式进行编排转换. 异构系统,功能繁多,复杂 代表性的项目有:J ...
- oracle count 百万级 分页查询记要总数、总条数优化
oracle count 百万级 分页查询记录总数.总条数优化 oracle count 百万级 查询记录总数.总条数优化 最近做一个项目时,做分页时,发现分页查询速度很慢,分页我做的是两次查询,一次 ...
- linux配置nodeJs环境教程
来自阿里云:https://help.aliyun.com/document_detail/50775.html
- egg.js 学习之 中间件使用
1.在框架和插件中使用中间件 编写中间件 我们先来通过编写一个简单的中间件,来看看中间件的写法. // app/middleware/middlewareOne.js // app/middlewar ...
- linux 5.7.20和5.6.38版本 数据库忘记root密码怎么找回?
1. 5.6.38版本的数据库密码丢失找回方法: 第一步.关数据库 第二步:mysqld_safe --skip-grant-tables --skip-networking & 第三步 ...
- Idea 搭建Maven--web项目(MVC)
小编最近正在学习使用MVC框架,在搭建Maven的项目过程中,遇到了很多问题,上网搜了很多材料才找到答案,为了小编以后查起来方便,也为了向广大小伙伴分享,写了这部片博文,敬我昨天一天的学习结果! 步骤 ...
- centos7系统优化
优化说明: 一.关闭selinux 二.更改为阿里yum源 三.提权dm用户可以使用sudo 四.优化ssh远程登录配置 五.设置中文字符集 六.设置时间同步 七.历史记录数及登录超时环境变量设置 八 ...
- django第10天(聚合查询,常用字段)
django第10天 聚合查询 聚合函数的使用场景 单独使用:不分组,只查聚合结果 分组使用:按字段分组,可查分组字段与聚合结果 导入聚合函数 from django.db.models import ...
- Python9-递归函数-day17
# 计算方法:人脑复杂,计算机简单#查找:找数据#排序#最短路径#我们学习的算法都是过去时#要了解基础的算法,才能创造出更好的算法#不是所有的事情都能套用现成的方法解决的# 有些时候会用到学过的算法只 ...
- c++ 快速幂 代码实现
懒得打代码系列… 不过这个代码挺短的死背下来也ok 解析在最下面 建议自己手动试个数据理解一下 比如 3^5 ^^ 原理:a ^ b = a ^ (b / 2) * 2 (b是奇数的话还要再乘一个a) ...