BZOJ1018:[SHOI2008]堵塞的交通
浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1018
我们把第一行和第二行的城市一起处理,对于每一个区间[\(l,r\)]的城市,我们需要维护下面六种关系:

一共六条边,分别用\(bool\)类型的六个变量来表示这六种联通关系是否成立。
然后询问两个城市是否联通,也许他们会绕出区间[\(l,r\)]再绕回来然后联通,所以有四种路径可以走;假设我询问的是一号城市和三号城市,二号城市是一号城市上方/下方的城市,四号城市是三号城市上方/下方的城市,那么这四条路径分别是:
一号---->三号(红色)
一号----》二号---->三号(绿色)
一号---->四号----》三号(蓝色)
一号----》二号---->四号----》三号(灰色)
其中>表示在区间内,》表示绕出去,如图所示:

时间复杂度:\(O(nlong)\)
空间复杂度:\(O(n)\)
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
int n;
char s[10];
bool bo[maxn*3];//bo数组里,[1,n-1]存的是第一行的道路,[n,2*n-1]存的是每一列的道路,[2*n,3*n-2]存的是第二行的道路。
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct tree_node {
bool a1,a2,a3,a4,a5,a6;
};
struct segment_tree {
tree_node tree[maxn<<2];
tree_node merge(tree_node f,tree_node g,int mid) {
tree_node res;int mid1=mid,mid2=mid+2*n-1;
res.a1=(f.a1)|(f.a2&&bo[mid1]&&g.a1&&bo[mid2]&&f.a4);
//f.a2&&bo[mid1]&&g.a1&&bo[mid2]&&f.a4 1号路径
//f.a5&&bo[mid2]&&g.a1&&bo[mid1]&&f.a6 2号路径
//如果2号路径存在那么1号路径必然存在,所以只需要判1号路径即可
res.a2=(f.a2&&bo[mid1]&&g.a2)|(f.a5&&bo[mid2]&&g.a6);
res.a3=(g.a3)|(g.a2&&bo[mid1]&&f.a3&&bo[mid2]&&g.a4);
res.a4=(f.a4&&bo[mid2]&&g.a4)|(f.a6&&bo[mid1]&&g.a5);
res.a5=(f.a2&&bo[mid1]&&g.a5)|(f.a5&&bo[mid2]&&g.a4);
res.a6=(f.a4&&bo[mid2]&&g.a6)|(f.a6&&bo[mid1]&&g.a2);
return res;
}
void build(int p,int l,int r) {
if(l==r) {
tree[p].a2=tree[p].a4=1;
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
void change(int p,int l,int r,int L,int R) {
if(l==r) {
if(L==R) {
tree[p].a1^=1;
tree[p].a3^=1;
tree[p].a5^=1;
tree[p].a6^=1;//如果是单点修改那么这四种关系应该改变状态
}
return;
}
int mid=(l+r)>>1;
if(L<=mid)change(p<<1,l,mid,L,R);
else change(p<<1|1,mid+1,r,L,R);
tree[p]=merge(tree[p<<1],tree[p<<1|1],mid);
}
tree_node query(int p,int l,int r,int L,int R) {
if(L<=l&&r<=R)return tree[p];
int mid=(l+r)>>1;tree_node res;
if(R<=mid)res=query(p<<1,l,mid,L,R);
else if(L>mid)res=query(p<<1|1,mid+1,r,L,R);
else res=merge(query(p<<1,l,mid,L,R),query(p<<1|1,mid+1,r,L,R),mid);
return res;
}
}T;
int main() {
n=read();T.build(1,1,n);
while(~scanf("%s",s+1)) {
if(s[1]=='E')break;
int x1=read(),y1=read(),x2=read(),y2=read();
if(y1>y2)swap(y1,y2),swap(x1,x2);
if(s[1]=='O'||s[1]=='C') {
if(x1==x2) {
int tmp=y1;
if(x1==2)tmp+=2*n-1;
bo[tmp]^=1;T.change(1,1,n,y1,y2);
}
else {
bo[y1+n-1]^=1;
T.change(1,1,n,y1,y2);
}
}
else {
bool ans=0;
tree_node j=T.query(1,1,n,1,y1);
tree_node k=T.query(1,1,n,y1,y2);
tree_node l=T.query(1,1,n,y2,n);
if(x1==x2) {
if(x1==1) {
ans|=k.a2;
ans|=j.a3&&k.a6;
ans|=k.a5&&l.a1;
ans|=j.a3&&k.a4&&l.a1;
}
else {
ans|=k.a4;
ans|=j.a3&&k.a5;
ans|=k.a6&&l.a1;
ans|=j.a3&&k.a2&&l.a1;
}
}
else {
if(x1==1) {
ans|=k.a5;
ans|=j.a3&&k.a4;
ans|=k.a2&&l.a1;
ans|=j.a3&&k.a6&&l.a1;
}
else {
ans|=k.a6;
ans|=j.a3&&k.a2;
ans|=k.a4&&l.a1;
ans|=j.a3&&k.a5&&l.a1;
}
}//对于询问的两个点的位置一共有四种不同的关系,分别分情况讨论
if(ans)puts("Y");
else puts("N");
}
}
return 0;
}
BZOJ1018:[SHOI2008]堵塞的交通的更多相关文章
- [bzoj1018][SHOI2008]堵塞的交通traffic_线段树
bzoj-1018 SHOI-2008 堵塞的交通traffic 参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html 题目大意:有一天,由于某 ...
- bzoj千题计划108:bzoj1018: [SHOI2008]堵塞的交通traffic
http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 ...
- [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MB Submit: 3795 Solved: 1253 [Sub ...
- BZOJ1018 [SHOI2008]堵塞的交通traffic
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- BZOJ1018[SHOI2008]堵塞的交通——线段树
题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总 ...
- [bzoj1018] [SHOI2008]堵塞的交通
题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个22行CC列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所 ...
- 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic
本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...
- 【线段树】bzoj1018 [SHOI2008]堵塞的交通traffic
线段树的每个叶子节点存一列. 每个节点维护六个域,分别是左上左下.左上右上.左上右下.左下右上.左下右下.右上右下在区间内部的连通性,不考虑绕出去的情况. 初始每个叶子的左上左下.右上右下是连通的. ...
- BZOJ1018 SHOI2008堵塞的交通(线段树)
动态图的连通性当然是可以用LCT维护的.但这相当的不优美,毕竟这样做没有用到任何该图的性质,LCT自带的大常数也会使其跑得非常慢. 考虑用线段树维护区间左右端四个点之间各自的连通性(仅经过该区间内路径 ...
- Bzoj1018[SHOI2008]堵塞的交通traffic(线段树)
这题需要维护连通性,看到有连接删除,很容易直接就想LCT了.然而这题点数20w操作10w,LCT卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...
随机推荐
- jsp获取web.xml 里的配置项
ServletContext servletContext = request.getSession().getServletContext(); String titl ...
- Linux kernel manpages
https://www.linuxquestions.org/questions/linux-newbie-8/man-pages-for-kernel-functions-758389/ 在Linu ...
- scapy windows install
最近有点扫描网络的需求,都说scapy好,但是安装是个事(当然指的是windows安装)有个scapy3k,支持python3,可惜需要powershell,也就是说windows xp是没有戏了. ...
- java 表示当前时间的第二天的几点
Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); cal.add(Calendar.DAY_OF_YEAR, 1); ...
- win7查看端口占用
1.查看谁占用了我们的80端口,在windows命令行窗口下执行: netstat -aon|findstr 80 发现80端口被进程号为2596的进程占用.2.查看占用80端口进程的应用程序是什 ...
- PowerBuilder -- 数据窗口
获取数据窗口列数 ls_colnum= integer(this.Describe("DataWindow.Column.Count")) 获取数据窗口列名 ls_colName ...
- 【PHP开发】ThinkPHP3.1.3问题集及解决方法
Outline: 无法获取post请求中的url参数的问题 中文存入数据表后为空字符串 1. 无法获取post请求中的url参数的问题 ThinkPHP3.1.3中,如果提交的post请求中,如果要在 ...
- android菜鸟学习笔记14----Android控件(三) ListView的简单使用
MVC模式: MVC的基本原理就是通过Controller连接View和Model.当View中所显示的数据发生变化时,会通知Controller,然后由Controller调用Model中的相关方法 ...
- 关于android R.java文件无法创建的问题
R.java文件无法创建的原因网上有很多说法普遍是以下两种: 1. xml文件有错误: 解决方法就是找到哪个xml有错然后把错误修复就OK了. 2.编码问题 这时候只要把xml文件的编码改成utf8就 ...
- PAT天梯赛 L2-002. 链表去重 【STL】
题目链接 https://www.patest.cn/contests/gplt/L2-002 思路 用结构体 存储 一个结点的地址 值 和下一个地址 然后从首地址开始 往下走 并且每个值的绝对值 都 ...