【BZOJ1018】[SHOI2008]堵塞的交通traffic

Description

  有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个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;

Input

  第一行只有一个整数C,表示网格的列数。接下来若干行,每行为一条交通信息,以单独的一行“Exit”作为结束。我们假设在一开始所有的道路都是堵塞的。我们保证 C小于等于100000,信息条数小于等于100000。

Output

  对于每个查询,输出一个“Y”或“N”。

Sample Input

2
Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit

Sample Output

Y
N

题解:先不考虑从两边走的情况,直接上线段树的区间合并即可。用f[0/1][0/1]表示从左上/左下能否走到右上/右下。

那么如果考虑从两边绕的情况呢?一定是贪心的选取第一个能拐的点就直接拐,所以在线段树上找到第一个拐点然后判断中间是否全部连通即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int maxn=100010;
int n,pre,nxt;
struct node
{
bool f[2][2],g[3],lp;
node () {memset(f,0,sizeof(f)),memset(g,0,sizeof(g)),lp=0;}
}s[maxn<<2];
node mix(node a,node b)
{
node c;
c.f[0][0]=(a.f[0][0]&b.f[0][0])|(a.f[0][1]&b.f[1][0])|(a.f[0][0]&b.f[1][0]&b.lp)|(a.f[0][1]&b.f[0][0]&b.lp);
c.f[0][1]=(a.f[0][0]&b.f[0][1])|(a.f[0][1]&b.f[1][1])|(a.f[0][0]&b.f[1][1]&b.lp)|(a.f[0][1]&b.f[0][1]&b.lp);
c.f[1][0]=(a.f[1][0]&b.f[0][0])|(a.f[1][1]&b.f[1][0])|(a.f[1][0]&b.f[1][0]&b.lp)|(a.f[1][1]&b.f[0][0]&b.lp);
c.f[1][1]=(a.f[1][0]&b.f[0][1])|(a.f[1][1]&b.f[1][1])|(a.f[1][0]&b.f[1][1]&b.lp)|(a.f[1][1]&b.f[0][1]&b.lp);
c.g[0]=a.g[0]&b.g[0],c.g[1]=a.g[1]&b.g[1],c.g[2]=a.g[2]|b.g[2],c.lp=a.lp;
return c;
}
char str[20];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void updata(int l,int r,int x,int a,int b,int c)
{
if(l==r)
{
s[x].g[b]=c,s[x].f[0][0]=s[x].g[0],s[x].f[1][1]=s[x].g[1],s[x].lp=s[x].g[2];
s[x].f[0][1]=s[x].g[2]&s[x].f[1][1],s[x].f[1][0]=s[x].g[2]&s[x].f[0][0];
return ;
}
int mid=(l+r)>>1;
if(a<=mid) updata(l,mid,lson,a,b,c);
else updata(mid+1,r,rson,a,b,c);
s[x]=mix(s[lson],s[rson]);
}
void getpre(int l,int r,int x,int a)
{
if(l>a||pre>=r||!s[x].g[2]) return ;
if(l==r)
{
pre=l;
return ;
}
int mid=(l+r)>>1;
getpre(mid+1,r,rson,a),getpre(l,mid,lson,a);
}
void getnxt(int l,int r,int x,int a)
{
if(r<a||nxt<=l||!s[x].g[2]) return ;
if(l==r)
{
nxt=l;
return ;
}
int mid=(l+r)>>1;
getnxt(l,mid,lson,a),getnxt(mid+1,r,rson,a);
}
node query(int l,int r,int x,int a,int b)
{
if(a>b)
{
node tmp;
tmp.f[0][0]=tmp.f[1][1]=tmp.g[0]=tmp.g[1]=1;
return tmp;
}
if(a<=l&&r<=b) return s[x];
int mid=(l+r)>>1;
if(b<=mid) return query(l,mid,lson,a,b);
if(a>mid) return query(mid+1,r,rson,a,b);
return mix(query(l,mid,lson,a,b),query(mid+1,r,rson,a,b));
}
int main()
{
n=rd();
int a1,b1,a2,b2;
while(1)
{
scanf("%s",str);
if(str[0]=='E') return 0;
a1=rd()-1,b1=rd(),a2=rd()-1,b2=rd();
if(b1>b2||(b1==b2&&a1>a2)) swap(a1,a2),swap(b1,b2);
if(str[0]=='C')
{
if(b1==b2) updata(1,n,1,b1,2,0);
else updata(1,n,1,b1,a1,0);
}
if(str[0]=='O')
{
if(b1==b2) updata(1,n,1,b1,2,1);
else updata(1,n,1,b1,a1,1);
}
if(str[0]=='A')
{
node tmp;
tmp=query(1,n,1,b1,b2-1);
if(tmp.f[a1][a2]) printf("Y\n");
else
{
pre=0,getpre(1,n,1,b1);
nxt=n+1,getnxt(1,n,1,b2);
node t1,t2;
if(pre) t1=query(1,n,1,pre,b1-1);
if(nxt!=n+1) t2=query(1,n,1,b2,nxt-1);
if(t1.g[0]&t1.g[1]&tmp.f[a1^1][a2]) printf("Y\n");
else if(t2.g[0]&t2.g[1]&tmp.f[a1][a2^1]) printf("Y\n");
else if(t1.g[0]&t1.g[1]&t2.g[0]&t2.g[1]&tmp.f[a1^1][a2^1]) printf("Y\n");
else printf("N\n");
}
}
}
}//4 Open 1 1 1 2 Open 1 1 2 1 Open 2 1 2 2 Open 2 2 2 3 Open 2 3 2 4 Open 1 4 2 4 Open 1 3 1 4 Ask 1 2 1 3

【BZOJ1018】[SHOI2008]堵塞的交通traffic 线段树的更多相关文章

  1. [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 3795  Solved: 1253 [Sub ...

  2. Bzoj1018[SHOI2008]堵塞的交通traffic(线段树)

    这题需要维护连通性,看到有连接删除,很容易直接就想LCT了.然而这题点数20w操作10w,LCT卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...

  3. bzoj1018[SHOI2008]堵塞的交通traffic——线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1018 巧妙的线段树.维护矩阵四个角的连通性. 考虑两个点连通的可能路径分成3部分:两点左边. ...

  4. [bzoj1018][SHOI2008]堵塞的交通traffic_线段树

    bzoj-1018 SHOI-2008 堵塞的交通traffic 参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html 题目大意:有一天,由于某 ...

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

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

  6. 【bzoj1018】[SHOI2008]堵塞的交通traffic 线段树区间合并+STL-set

    题目描述 给出一张2*n的网格图,初始每条边都是不连通的.多次改变一条边的连通性或询问两个点是否连通. 输入 第一行只有一个整数C,表示网格的列数.接下来若干行,每行为一条交通信息,以单独的一行“Ex ...

  7. BZOJ1018 SHOI2008堵塞的交通(线段树)

    动态图的连通性当然是可以用LCT维护的.但这相当的不优美,毕竟这样做没有用到任何该图的性质,LCT自带的大常数也会使其跑得非常慢. 考虑用线段树维护区间左右端四个点之间各自的连通性(仅经过该区间内路径 ...

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

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

  9. 【BZOJ1018】堵塞的交通(线段树)

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

随机推荐

  1. win10+anaconda3+pytorch安装

    安装条件:win10+anaconda3+tf-gpu+pytorch 安装完tf-gpu后,安装pytorch. pytorch采用conda安装:见 https://ptorch.com/news ...

  2. 牛客网 牛客小白月赛1 F.三视图

    F.三视图   链接:https://www.nowcoder.com/acm/contest/85/F来源:牛客网     这个题自己想一下三维的,正视图和左视图中y轴为行数,x轴和z轴是列数,因为 ...

  3. POJ1655 Balancing Act(树的重心)

    题目链接 Balancing Act 就是求一棵树的重心,然后统计答案. #include <bits/stdc++.h> using namespace std; #define REP ...

  4. POJ 1961 Period KMP算法之next数组的应用

    题意:给一个长度为n的字符串,如果它长度为l(2 <= l <= n)的前缀部分是由一些相同的字符串相接而成,输出前缀的长度l和长度为l时字符串重复的最大次数. 例如字符串为: aaaba ...

  5. FactoryMethod

    工厂方法模式 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类 工厂方法的简单实现 (1)创建简单的产品接口 /** * 创建产品接口 * @autho ...

  6. 命令提示符中运行SQL Server 2005

      使用 sqlcmd 实用工具,可以在命令提示符处.SQLCMD 模式下的查询编辑器.Windows 脚本文件或 SQL Server 代理作业的操作系统 (Cmd.exe) 作业步骤中,输入 Tr ...

  7. Can''t find the channel handler for deviceType 工行 个人网银 错误

    背景描述:系统Win7,浏览器IE8.登录工商银行个人网银的时候,输入帐号密码和验证码后,出现空白页面,上面一句话  Can''t find the channel handler for devic ...

  8. 解决Ubuntu下gedit中文乱码的情况

    windows下简体中文多用GBK编码 (或GB2312, GB18030), 而linux下多用UTF-8编码. 因此,一般来说在微软平台编辑的中文txt不能在ubuntu下直接打开查看,除非在保存 ...

  9. C#是唯一能挑战Java的编程语言?

    几乎所有新近成长的Visual Studio代码开发人员都选择使用C#,而不是VB.NET或C++,这也使得C#已经成长为微软的第一大语言.根据本月的Tiobe编程语言排行榜,C#再次取得了突破性进展 ...

  10. 【性能优化】——前端性能优化之DOM

    前言:本文参考学习自 RenChao Guan的博客,来源FSUX.ME,感谢原作者,本文的思维导图为自己整理 补充: 浏览器工作流程 避免重绘和回流的四种方式的具体实现