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卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...
随机推荐
- Linux QtCreator 设置mingw编译器生成windows程序
Qt跨平台,那必须在Linux平台编译一个可以在windows下运行的Qt程序才行,当然还得和QtCreator环境弄在一起才行 工作环境:Centos 7 yum install qt5-qt* m ...
- Excel COM组件使用的注意事项和一些权限问题(转载)
1.实例化Excel的COM组件的时候,不要直接调用类,要用Microsoft提供的接口 原来的写法:Excel.ApplicationClass excelApp = new Excel.Appli ...
- Docker入门系列8
commit docker commit -m "Added json gem" -a "Docker Newbee" 0b2616b0e5a8 ouruser ...
- JavaScrip函数与声明表达式
首先我们看下函数的两种命名方式 1.函数声明,声明一个函数 function test1(){ var a=0; console.log(a); //左一些操作... } 执行结果如下 我们看一下,无 ...
- JS常用方法手记
1.判断arr数组是否含有元素str,没有返回-1 arr.indexOf(str) 2.遍历arr数组,k为键,v为值 arr.map((v, k) => { return;}) 3.arr数 ...
- iOS 键盘变中文
plist文件添加 Localizations 添加一项字段Chinese (simplified)
- H2 应用实例1
说明:本例子开发工具为NetBeans,jdk 1.7 进行测试说明 H2安装说明如下 1. H2数据库必要文件下载地址为: http://www.h2database.com (1) 下载截 ...
- vs2013工程下的各个文件和文件夹的作用
1 ipch文件夹 用来加速编译,里面存放的是precompiled headers,即预编译好了的头文件. 头文件也是需要编译的,比如需要处理#ifdef,需要替换宏以及需要include其它头文件 ...
- 【题解】Jury Compromise(链表+DP)
[题解]Jury Compromise(链表+DP) 传送门 题目大意 给你\(n\le 200\)个元素,一个元素有两个特征值,\(c_i\)和\(d_i\),\(c,d \in [0,20]\), ...
- 我的Android进阶之旅------>Android实现音乐示波器、均衡器、重低音和音场功能
本实例来自于<疯狂Android讲义>,要实现具体的功能,需要了解以下API: MediaPlayer 媒体播放器 Visualizer 频谱 Equalizer 均衡器 BassBoo ...