1018: [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit: 162 MB
Submit: 3242  Solved: 1084
[Submit][Status][Discuss]

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
 
 
【分析】
  
  线段树真是太多功能了。
  简单说一下:
  线段树的点[L,R]维护六个bool,表示[1,L][2,L][1,R][2,R]两两之间的,只在这个区间内的边上走的连通性。
  修改的时候从最下面update上去,[L,MID][MID+1,R]两区间合并不用说了吧。。。
  询问的时候分成三个区间[1,L-1][L,R][R+1,N]
  先问[L,R]之间能不能使他联通,不然,还有三种情况,
 
  
  三个都判断一下就好了,【我还漏了第三种  TAT
 
代码好丑:
 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 100010 char s[]; struct node
{
int l,r,lc,rc;
bool c11,c12,c21,c22,cl,cr;
}tr[Maxn*]; bool cn[][Maxn],cn2[Maxn]; void upd(int x)
{
if(tr[x].l==tr[x].r) return;
int lc=tr[x].lc,rc=tr[x].rc;
int mid=(tr[x].l+tr[x].r)>>;
tr[x].c11=tr[x].c12=tr[x].c21=tr[x].c22=tr[x].cl=tr[x].cr=;
if(tr[lc].c11&&tr[rc].c11&&cn[][mid]) tr[x].c11=;
if(tr[lc].c12&&tr[rc].c21&&cn[][mid]) tr[x].c11=; if(tr[lc].c11&&tr[rc].c12&&cn[][mid]) tr[x].c12=;
if(tr[lc].c12&&tr[rc].c22&&cn[][mid]) tr[x].c12=; if(tr[lc].c21&&tr[rc].c11&&cn[][mid]) tr[x].c21=;
if(tr[lc].c22&&tr[rc].c21&&cn[][mid]) tr[x].c21=; if(tr[lc].c21&&tr[rc].c12&&cn[][mid]) tr[x].c22=;
if(tr[lc].c22&&tr[rc].c22&&cn[][mid]) tr[x].c22=; if((tr[lc].c11&&tr[lc].c22&&tr[rc].cl&&cn[][mid]&&cn[][mid])||tr[lc].cl) tr[x].cl=;
if((tr[rc].c11&&tr[rc].c22&&tr[lc].cr&&cn[][mid]&&cn[][mid])||tr[rc].cr) tr[x].cr=;
} int tot;
int build(int l,int r)
{
int x=++tot;
tr[x].l=l;tr[x].r=r;
tr[x].c11=tr[x].c12=tr[x].c21=tr[x].c22=tr[x].cl=tr[x].cr=;
if(l!=r)
{
int mid=(l+r)>>;
tr[x].lc=build(l,mid);
tr[x].rc=build(mid+,r);
}
else tr[x].lc=tr[x].rc=,tr[x].c11=tr[x].c22=tr[x].cl=tr[x].cr=;
return x;
} void change(int x,int l,int r)
{
if(tr[x].l==tr[x].r)
{
if(cn2[l]) tr[x].c12=tr[x].c21=tr[x].cl=tr[x].cr=;
else tr[x].c12=tr[x].c21=tr[x].cl=tr[x].cr=;
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if(r<=mid) change(tr[x].lc,l,r);
else if(l>mid) change(tr[x].rc,l,r);
else
{
change(tr[x].lc,l,mid);
change(tr[x].rc,mid+,r);
}
upd(x);
} bool a11,a12,a21,a22,al,ar;
void query(int x,int l,int r)
{
if(tr[x].l==l&&tr[x].r==r)
{
a11=tr[x].c11;
a12=tr[x].c12;
a21=tr[x].c21;
a22=tr[x].c22;
al=tr[x].cl;ar=tr[x].cr;
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if(r<=mid) query(tr[x].lc,l,r);
else if(l>mid) query(tr[x].rc,l,r);
else
{
bool b11,b12,b21,b22,bl,br,c11,c12,c21,c22,cl,cr;
query(tr[x].lc,l,mid);b11=a11;b12=a12;b21=a21;b22=a22;bl=al;br=ar;
query(tr[x].rc,mid+,r);c11=a11;c12=a12;c21=a21;c22=a22;cl=al;cr=ar;
a11=a12=a21=a22=al=ar=;
if(b11&&c11&&cn[][mid]) a11=;
if(b12&&c21&&cn[][mid]) a11=; if(b11&&c12&&cn[][mid]) a12=;
if(b12&&c22&&cn[][mid]) a12=; if(b21&&c11&&cn[][mid]) a21=;
if(b22&&c21&&cn[][mid]) a21=; if(b21&&c12&&cn[][mid]) a22=;
if(b22&&c22&&cn[][mid]) a22=;
if((b11&&b22&&cl&&cn[][mid]&&cn[][mid])||bl) al=;
if((c11&&c22&&br&&cn[][mid]&&cn[][mid])||cr) ar=;
}
} int main()
{
int n;
scanf("%d",&n);
tot=;
build(,n);
for(int i=;i<=n;i++) cn[][i]=cn[][i]=cn2[i]=;
while()
{
scanf("%s",s);
if(s[]=='E') break;
int r1,c1,r2,c2;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
// if(c1>c2) swap(c1,c2);
if(c1>c2||(c1==c2&&r1>r2))
{
swap(r1,r2);swap(c1,c2);
// int tt;
// tt=r1,r1=r2,r1=tt;
// tt=c1,c1=c2,c2=tt;
}
if(s[]=='O')
{
if(r1==r2) cn[r1-][c1]=;
else cn2[c1]=;
change(,c1,c2);
}
else if(s[]=='C')
{
if(r1==r2) cn[r1-][c1]=;
else cn2[c1]=;
change(,c1,c2);
}
else
{
if(r1==r2&&c1==c2) {printf("Y\n");continue;}
a11=a12=a21=a22=al=ar=;
query(,c1,c2);
if(r1==&&r2==&&a11) printf("Y\n");
else if(r1==&&r2==&&a12) printf("Y\n");
else if(r1==&&r2==&&a21) printf("Y\n");
else if(r1==&&r2==&&a22) printf("Y\n");
else
{
bool b11,b12,b21,b22;
b11=a11;b12=a12;b21=a21;b22=a22;
bool ok=,p1=,p2=;
if(cn[][c1-]&&cn[][c1-])
{
a11=a12=a21=a22=al=ar=;
query(,,c1-);if(ar)
if((r2==&&(b11||b21))||(r2==&&(b12||b22))) {ok=;printf("Y\n");}
if(ar) p1=;
}
if(!ok&&cn[][c2]&&cn[][c2]&&c2<n)
{
a11=a12=a21=a22=al=ar=;
query(,c2+,n);if(al)
if((r1==&&(b11||b12))||(r1==&&(b21||b22))) {ok=;printf("Y\n");}
if(al) p2=;
}
if(!ok&&p1&&p2&&cn[][c1-]&&cn[][c1-]&&cn[][c2]&&cn[][c2]&&c2<n)
{
if(b11||b12||b21||b22) {ok=;printf("Y\n");}
}
if(!ok) printf("N\n");
}
}
}
return ;
}

2017-03-08 13:27:45

【BZOJ 1018】线段树 **的更多相关文章

  1. bzoj 1018 线段树维护连通性

    本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护. 对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边 ...

  2. BZOJ 1018 线段树维护图的连通性问题

    思路: 我们可以搞一棵线段树 对于一段区间有6种情况需要讨论 左上右下.左上右上.左下右下.左下右上 这四种比较好维护 用左上右下举个例子吧 就是左儿子的左上右下&左区间到右区间下面有路&am ...

  3. BZOJ 1018 线段树维护图连通性

    用8个bool维护即可分别为LURU,LURD,LDRU,LDRD,LULD,RURD,Side[1],Side[2]即可. Side表示这一块有没有接到右边.Merge一下就可以了.码农题,WA了一 ...

  4. BZOJ 1798 (线段树||分块)的标记合并

    我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...

  5. bzoj 3999 线段树区间提取 有序链剖

    看错题目了,想成每个城市都可以买一个东西,然后在后面的某个城市卖掉,问最大收益.这个可以类似维护上升序列的方法在O(nlog^3n)的时间复杂度内搞定 这道题用到的一些方法: 1. 可以将有关的线段提 ...

  6. bzoj 3211 线段树

    开方操作最多进行5次就可以把出现的任何数变成1. 所以用线段树暴力修改,以后修改时只需看一下是否当前区间都是0或1,如果是那么就直接返回. /***************************** ...

  7. bzoj 3212 线段树

    裸的线段树 /************************************************************** Problem: User: BLADEVIL Langua ...

  8. bzoj 2120 线段树套平衡树

    先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...

  9. bzoj 1901 线段树套平衡树+二分答案查询

    我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案, 查询每个二分到的mid在这个区间里的rank,然后就行了 /************************* ...

  10. BZOJ 1012 线段树||单调队列

    非常裸的线段树  || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...

随机推荐

  1. VS 2010 应用程序无法启动

    其实一般遇到这种问题, 不管是debug还是release, 也不用看提示的内存地址, 首先应该想到库是否包含正确. 一个可能的错误就是32位或64位不匹配的错误. 比如环境变量设的是64位的Open ...

  2. c语言学习笔记.指针.

    指针: 一个变量,其值为另一个变量的地址,即,内存位置的直接地址. 声明: int *ptr; /* 一个整型的指针,指针指向的类型是整型 */ double *ptr; /* 一个 double 型 ...

  3. 第三讲:ifconfig:最熟悉又陌生的命令行

    你知道怎么查看IP地址吗? 当面试听到这个问题的时候,面试者常常会觉得走错了房间.我面试的是技术岗位啊,怎么问这么简单的问题? 的确,即便没有专业学过计算机的人,只要倒腾过电脑,重装过系统,大多也会知 ...

  4. Feather包实现数据框快速读写,你值得拥有

    什么是Feather? Feature是一种文件格式,支持R语言和Python的交互式存储,速度更快.目前支持R语言的data.frame和Python pandas 的DataFrame. Feat ...

  5. KKT条件和拉格朗日乘子法详解

    \(\frac{以梦为马}{晨凫追风}\) 最优化问题的最优性条件,最优化问题的解的必要条件和充分条件 无约束问题的解的必要条件 \(f(x)\)在\(x\)处的梯度向量是0 有约束问题的最优性条件 ...

  6. [ python ] 网络编程(2)

    黏包问题 这样一个实例 import socket import subprocess sk_server = socket.socket() # 创建 socket对象 sk_server.bind ...

  7. java之正则表达式、日期操作

    正则表达式和日期操作 正则表达式简介 正则表达式就是使用一系列预定义的特殊字符来描述一个字符串的格式规则,然后使用该格式规则匹配某个字符串是否符合格式要求. 作用:比如注册邮箱,邮箱有用户名和密码,一 ...

  8. java基础13 接口(及关键字:interface、implements)

    接口 1.接口的定义格式 interface 接口名{ } interface :接口的关键字 implements:实现接口的关键字 2.接口的作用 1.程序的解耦.(低耦合)        2.定 ...

  9. Oracle数据库,基础知识

    1.Oracle的五大约束条件: 1 主键  primary key2 外键  foreign key,3 唯一  unique,4 检测  check5 非空  not null 实例运用: -- ...

  10. 详解Oracle的unlimited tablespace系统权限

    1. 系统权限unlimited tablespace是隐含在dba, resource角色中的一个系统权限. 当用户得到dba或resource的角色时, unlimited tablespace系 ...