题目链接

只有两行,可能的路径数不多,考虑用线段树维护各种路径的连通性。

每个节点记录luru(left_up->right_up),lurd,ldru,ldrd,luld,rurd,表示这个区间对应的连通信息。

合并时 横向道路需要用两个数组up[],down[]记录连通性;纵向道路在修改时直接单点改,再PushUp。

询问时连通的可能性有多种,都需判断。

//5708kb	768ms
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=1e5+5; int n,tot;//root=0
bool road[2][N];
struct Node
{
int l,r,ls,rs;
bool luru,lurd,ldru,ldrd,luld,rurd;
}node[N<<1]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
#define now node[rt]
#define nls node[ls]
#define nrs node[rs]
void Build(int l,int r)
{
int p=tot++; node[p].l=l, node[p].r=r;
if(l==r) node[p].luru=node[p].ldrd=1;//这个初始化要有。
else{
int m=l+r>>1;
node[p].ls=tot, Build(l,m),
node[p].rs=tot, Build(m+1,r);
}
}
//void Print(Node rt){
// printf("%d~%d\nluru:%d lurd:%d ldru:%d ldrd:%d luld:%d rurd:%d\n",rt.l,rt.r,rt.luru,rt.lurd,rt.ldru,rt.ldrd,rt.luld,rt.rurd);
//}
inline void Update(int rt)
{
int ls=now.ls,rs=now.rs,p=node[ls].r;
now.luru=(nls.luru&&road[0][p]&&nrs.luru)||(nls.lurd&&road[1][p]&&nrs.ldru);
now.lurd=(nls.luru&&road[0][p]&&nrs.lurd)||(nls.lurd&&road[1][p]&&nrs.ldrd);
now.ldru=(nls.ldrd&&road[1][p]&&nrs.ldru)||(nls.ldru&&road[0][p]&&nrs.luru);
now.ldrd=(nls.ldrd&&road[1][p]&&nrs.ldrd)||(nls.ldru&&road[0][p]&&nrs.lurd);
now.luld=nls.luld||(nls.luru&&road[0][p]&&nrs.luld&&road[1][p]&&nls.ldrd);
now.rurd=nrs.rurd||(nrs.luru&&road[0][p]&&nls.rurd&&road[1][p]&&nrs.ldrd);
}
Node Merge(const Node &ls,const Node &rs)
{
Node tmp;
int p=ls.r; tmp.l=ls.l, tmp.r=rs.r;//左右端点要更新!(p)
tmp.luru=(ls.luru&&road[0][p]&&rs.luru)||(ls.lurd&&road[1][p]&&rs.ldru);
tmp.lurd=(ls.luru&&road[0][p]&&rs.lurd)||(ls.lurd&&road[1][p]&&rs.ldrd);
tmp.ldru=(ls.ldrd&&road[1][p]&&rs.ldru)||(ls.ldru&&road[0][p]&&rs.luru);
tmp.ldrd=(ls.ldrd&&road[1][p]&&rs.ldrd)||(ls.ldru&&road[0][p]&&rs.lurd);
tmp.luld=ls.luld||(ls.luru&&road[0][p]&&rs.luld&&road[1][p]&&ls.ldrd);
tmp.rurd=rs.rurd||(rs.luru&&road[0][p]&&ls.rurd&&road[1][p]&&rs.ldrd);
return tmp;
}
void Modify_Row(int rt,int p,bool is_down,bool v)
{
int m=now.l+now.r>>1;
if(m==p){//当前区间从m处与m+1断开,所以应该在这更新!
road[is_down][m]=v;
if(now.l!=now.r) Update(rt);
}
else{
if(p<=m) Modify_Row(now.ls,p,is_down,v);
else Modify_Row(now.rs,p,is_down,v);
Update(rt);
}
}
void Modify_Col(int rt,int p,bool v)
{
if(now.l==now.r)
/*now.luru=now.ldrd=*/now.lurd=now.ldru=now.luld=now.rurd=v;//更新列之间的就可以了?
else{
int m=now.l+now.r>>1;
if(p<=m) Modify_Col(now.ls,p,v);
else Modify_Col(now.rs,p,v);
Update(rt);
}
}
Node Query(int rt,int L,int R)
{
if(L<=now.l && now.r<=R) return now;
int m=now.l+now.r>>1;
if(L<=m)
if(m<R) return Merge(Query(now.ls,L,R),Query(now.rs,L,R));
else return Query(now.ls,L,R);
return Query(now.rs,L,R);
}
void Ask(int r1,int c1,int r2,int c2)
{
Node l=Query(0,1,c1),m=Query(0,c1,c2),r=Query(0,c2,n);//由这三个位置去判断
// Print(l), Print(m), Print(r);
if(r1==1 && r2==1)
{
if ((m.luru)||
(m.lurd&&r.luld)||
(m.ldru&&l.rurd)||
(l.rurd&&m.ldrd&&r.luld)) puts("Y");
else puts("N");
}
else if(r1==2 && r2==2)
{
if ((m.ldrd)||
(m.ldru&&r.luld)||
(m.lurd&&l.luld)||
(l.rurd&&m.luru&&r.luld)) puts("Y");
else puts("N");
}
else if(r1==1)//r2==2
{
if ((m.lurd)||
(m.luru&&r.luld)||
(m.ldrd&&l.rurd)||
(l.rurd&&m.ldru&&r.luld)) puts("Y");
else puts("N");
}
else if(r1==2)//r2==1
{
if ((m.ldru)||
(m.ldrd&&r.luld)||
(m.luru&&l.rurd)||
(l.rurd&&m.lurd&&r.luld)) puts("Y");
else puts("N");
}
}
//void Print_All(int rt){
// if(now.ls) Print_All(now.ls);
// Print(node[rt]);
// if(now.rs) Print_All(now.rs);
//} int main()
{
n=read(), Build(1,n);
char opt[3]; int r1,r2,c1,c2;
// Print_All(0);
while(scanf("%s",opt), opt[0]!='E')
{
r1=read(),c1=read(),r2=read(),c2=read();
if(c1>c2) std::swap(r1,r2),std::swap(c1,c2);//不是在r1>r2的时候换。
if(opt[0]=='C')
if(r1==r2) Modify_Row(0,c1,r1==2,0);
else Modify_Col(0,c1,0);
else if(opt[0]=='O')
if(r1==r2) Modify_Row(0,c1,r1==2,1);
else Modify_Col(0,c1,1);
else Ask(r1,c1,r2,c2);
// Print_All(0);
}
return 0;
}

BZOJ.1018.[SHOI2008]堵塞的交通(线段树维护连通性)的更多相关文章

  1. BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3064  Solved: 1027[Submi ...

  2. 数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2638  Solved: 864 Descri ...

  3. BZOJ 1018 [SHOI2008]堵塞的交通traffic

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2247  Solved: 706[Submit ...

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

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

  5. 洛谷 4246 BZOJ 1018 [SHOI2008]堵塞的交通

    [题解] 原来线段树还可以这么玩.. 我们用线段树维护连通性.对于一个矩形,我们用4个标记维护4个点的联通情况,再用两个标记维护右边两个点与它们右边的与它们在同一行的点的联通情况. 画图表示,就是 另 ...

  6. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  7. [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

    题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...

  8. BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1018 用线段树维护区间连通性,对于每一个区间记录6个域表示(左上,左下)(左上,右上)(右上, ...

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

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

随机推荐

  1. Python序列化与反序列化-json与pickle

    Python序列化与反序列化-json与pickle 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.json的序列化方式与反序列化方式 1>.json序列化 #!/usr ...

  2. bzoj千题计划255:bzoj3572: [Hnoi2014]世界树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3572 明显需要构造虚树 点属于谁管理分三种情况: 1.属于虚树的点 2.在虚树上的边上的点 3.既不 ...

  3. 读书笔记:《思考的乐趣:Matrix67数学笔记》第4章 统计数据的陷阱

    <思考的乐趣:Matrix67数学笔记>第4章讲了几个统计学上的陷阱,由于现在流行的大数据与统计学很有渊源,所以认真读了这一章,在<大数据时代>中指出只考虑相关性就够了,而不考 ...

  4. javascript惰性函数

    惰性函数:所谓惰性函数就是创建了一个新函数并且将其分配给保存了另外函数的同一个变量,就以一个新函数覆盖了旧函数.某种程度上,回收了旧函数指针以指向一个新函数. 板栗: var scareMe = fu ...

  5. (P2022 有趣的数)||(zoj Little Sub and Mr.Potato's Math Problem)(思维)

    题目链接:https://www.luogu.org/problemnew/show/P2022 题目大意:中文题目 具体思路: 第一步:我们可以先计算出当前的数前面按照字典序的话,前面有多少数(包括 ...

  6. 【PE结构】恶意代码数字签名验证

    说明 恶意代码数字签名验证功能,WinverityTrust.CryptQueryObject 代码实现 WinVerifyTrust //------------------------------ ...

  7. [Android]Eclipse 安装 ADT[Android Development Tooling] 失败的两种解决办法

    原因 最近想在新装的 Win7 里搭建一下 Android 的开发环境,虽然现在有 Android Studio 了,不过还是习惯 Eclipse 一点.众所周知的原因,Eclipse 直接安装 AD ...

  8. [原创]Python/Django使用富文本编辑器XHeditor上传本地图片

    前言 为了在Django框架下使用Xheditor上传图片,居然折腾了我一个晚上.期间也遇到种种问题,网上相关资料极少.现在把经验分享给大家. 正文 xheditor篇 1.下载http://xhed ...

  9. 面试经典---数据库索引B+、B-树

    大型数据库数据都是存在硬盘中的,为了操作的速度,需要设计针对外存的数据结构.而数据库索引技术就是在面试中反复被问到的一个问题:数据库索引是怎么实现的?数据库索引越大越好吗? 需要详细了解下这方面的知识 ...

  10. Luogu P1318 积水面积

    题目描述 一组正整数,分别表示由正方体迭起的柱子的高度.若某高度值为x,表示由x个正立方的方块迭起(如下图,0<=x<=5000).找出所有可能积水的地方(图中蓝色部分),统计它们可能积水 ...