【题解】

  原来线段树还可以这么玩。。

  我们用线段树维护连通性。对于一个矩形,我们用4个标记维护4个点的联通情况,再用两个标记维护右边两个点与它们右边的与它们在同一行的点的联通情况。

  画图表示,就是

    

  另一个关键问题是对于询问(r1,c1,r2,c2),并不是只可以走c1到c2之间的部分,它可以绕路走,这就需要我们在处理询问的时候把c1,c2进行扩展。具体说来,就是让c1一直向左走,让c2一直向右走,

然后查询新的(r1,c1,r2,c2). 为什么这样做是对的呢?

  

  

  通过上图我们可以发现要绕路走必须走到跟r1,r2不同的行,也就是一定会通过c1左边的竖着的边以及c2右边的竖着的边。而且一定存在一种走法使得绕路走的部分形成一个类似括号的形状。我们把c1一直左移得到c1',就可以保证[c1',c1]之间一定有竖着的边(如果c1到c1左边联通的部分之间有竖边存在的话)。右边的c2也是同理。这样查询新的c1,c2就转化成了没有绕路走的情况。

 // luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#define N 100010
#define rg register
#define ls (u<<1)
#define rs (u<<1|1)
using namespace std;
int n;
struct tree{
int t1,t2,t3,t4,t5,t6;
}a[N<<];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
inline void pushup(int u){
a[u].t1=(a[ls].t1&&a[ls].t5&&a[rs].t1)||(a[ls].t3&&a[ls].t6&&a[rs].t4);
a[u].t2=(a[ls].t2&&a[ls].t6&&a[rs].t2)||(a[ls].t4&&a[ls].t5&&a[rs].t3);
a[u].t3=(a[ls].t1&&a[ls].t5&&a[rs].t3)||(a[ls].t3&&a[ls].t6&&a[rs].t2);
a[u].t4=(a[ls].t4&&a[ls].t5&&a[rs].t1)||(a[ls].t2&&a[ls].t6&&a[rs].t4);
a[u].t5=a[rs].t5;
a[u].t6=a[rs].t6;
}
void build(int u,int l,int r){
if(l<r){
int mid=(l+r)>>;
build(ls,l,mid); build(rs,mid+,r);
}
else a[u].t1=a[u].t2=;
}
void update(int u,int l,int r,int pos,int type,int del){
if(l==r){
if(type==||type==) a[u].t3=a[u].t4=del;
if(type==) a[u].t5=del;
if(type==) a[u].t6=del;
return;
}
int mid=(l+r)>>;
if(pos<=mid) update(ls,l,mid,pos,type,del);
else update(rs,mid+,r,pos,type,del);
pushup(u);
}
tree query(int u,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return a[u];
tree ret,L,R; int mid=(l+r)>>;
L=R=(tree){,,,,,};
if(ql<=mid) ret=L=query(ls,l,mid,ql,qr);
if(qr>mid) ret=R=query(rs,mid+,r,ql,qr);
if(ql<=mid&&qr>mid){
ret.t1=(L.t1&&L.t5&&R.t1)||(L.t3&&L.t6&&R.t4);
ret.t2=(L.t2&&L.t6&&R.t2)||(L.t4&&L.t5&&R.t3);
ret.t3=(L.t1&&L.t5&&R.t3)||(L.t3&&L.t6&&R.t2);
ret.t4=(L.t4&&L.t5&&R.t1)||(L.t2&&L.t6&&R.t4);
}
return ret;
}
int goleft(int u,int l,int r,int type,int pos){
if(r==pos&&((type==&&a[u].t1)||(type==&&a[u].t2))) return l;
int mid=(l+r)>>;
if(pos<=mid) return goleft(ls,l,mid,type,pos);
int L=goleft(rs,mid+,r,type,pos);
if(L==mid+&&((type==&&a[ls].t5)||(type==&&a[ls].t6)))
return goleft(ls,l,mid,type,mid);
return L;
}
int goright(int u,int l,int r,int type,int pos){
if(l==pos&&((type==&&a[u].t1)||(type==&&a[u].t2))) return r;
int mid=(l+r)>>;
if(pos>mid) return goright(rs,mid+,r,type,pos);
int R=goright(ls,l,mid,type,pos);
if(R==mid&&((type==&&a[ls].t5)||(type==&&a[ls].t6)))
return goright(rs,mid+,r,type,mid+);
return R;
}
int main(){
n=read(); build(,,n);
while(){
char s[]; scanf("%s",s+);
while(s[]!='E'&&s[]!='C'&&s[]!='O'&&s[]!='A') scanf("%s",s+);
if(s[]=='E') break;
int r1=read(),c1=read(),r2=read(),c2=read();
if(c1>c2) swap(c1,c2),swap(r1,r2);
if(s[]=='C'){
if(c1==c2) update(,,n,c1,,);
if(r1==r2) update(,,n,c1,r1==?:,);
}
if(s[]=='O'){
if(c1==c2) update(,,n,c1,,);
if(r1==r2) update(,,n,c1,r1==?:,);
}
if(s[]=='A'){
c1=goleft(,,n,r1,c1); c2=goright(,,n,r2,c2);
tree ans=query(,,n,c1,c2);
bool flag=;
if(r1==&&r2==) flag=ans.t1;
if(r1==&&r2==) flag=ans.t2;
if(r1==&&r2==) flag=ans.t3;
if(r1==&&r2==) flag=ans.t4;
puts(flag?"Y":"N");
}
}
return ;
}

洛谷 4246 BZOJ 1018 [SHOI2008]堵塞的交通的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树分治+并查集)

    传送门 解题思路 可以离线,然后确定每个边的出现时间,算这个排序即可.然后就可以线段树分治了,连通性用并查集维护,因为要撤销,所以要按秩合并,时间复杂度\(O(nlog^2 n)\) 代码 #incl ...

  8. 1018: [SHOI2008]堵塞的交通traffic

    1018: [SHOI2008]堵塞的交通traffic 链接 分析: 用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可. 六种情况左上到右上(左边到右边的情况)… ...

  9. 【BZOJ】1018: [SHOI2008]堵塞的交通traffic

    http://www.lydsy.com/JudgeOnline/problem.php?id=1018 题意:有2行,每行有c(c<=100000)个城市,则一共有c-1个格子,现在有q(q& ...

随机推荐

  1. C#面向过程之类型转换、算术运算符、关系运算符、逻辑运算符、if-else语句、switch-case、循环结构(while、for)、三元表达式

    数据类型转换: int.parse()只能转换string类型的 当参数为null时会报异常int i =Convert.ToInt32(false) 运行结果是0int i =Convert.ToI ...

  2. Android 在eclipse中没有出现AVD的解决方法(转载)

    转自:http://frabbit2013.blog.51cto.com/1067958/1243549 本文主要介绍在系统中成功配置好Android开发环境(即SDK is ok and ADT o ...

  3. oracle给用户授权

    1.在PLSQL里,用sys(oracle系统用户)登陆,登陆的时候一定要选择SYSDBA.普通用户登陆选择normal就可以了 2.创建用户 *也可以给普通用户授权为dba即数据库管理员.在导入导出 ...

  4. SAP基本搜索帮助及增强出口

    se11创建基本搜索帮助时,各个参数的含意 选择方法   指定命中列表的数据来源,可以是数据库表,视图,CDS.如果指定了搜索帮助出口函数则该字段可以不输,数据来源可以在出口中自行指定 对话类型: 输 ...

  5. boxworld开发日记2019-6-8

    打算做一个类似RimWorld的游戏,这里记录一下历程.首先,简单回顾一下. 2018年12月23日  场景管理,打算使用四叉树,后来发现四叉树在空间组织和内存占用方面并不占优势,之后计划使用地图分块 ...

  6. C# 传值和传引用 ( ref out in )

    引用类型的变量不直接包含其数据:它包含的是对其数据的引用.当通过值传递引用类型的参数时,有可能更改引用所指向的数据,如某类成员的值(更改属性的值),但是无法更改引用本身的值:也就是说,不能使用相同的引 ...

  7. 所有版本chrome、chromedriver、firefox下载链接

    1. 所有版本chrome下载 是不是很难找到老版本的chrome?博主收集了几个下载chrome老版本的网站,其中哪个下载的是原版的就不得而知了. http://www.slimjet.com/ch ...

  8. Angular JS中自定义标签 属性绑定的解释

    看到自定义标签的文档时,文档作者解释的能力实在太弱,也可能是本人太笨,一下绕不过来. 看了一个stackoverflow答案,才算明白,在此贴出翻译,以供大家参考. .csharpcode, .csh ...

  9. Unity笔记(2)自学第一天

    学习记录: 界面使用:

  10. mysql 存储引擎学习

    现在我们常用的MySQL存储引擎主要是两种:InnoDB and MyISAM. 1.MyISAM 执行效率高 不支持事务 不支持外键 每个MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同, ...