[BZOJ1018]SHOI2008堵塞的交通|线段树

[BZOJ]1018 堵塞交通 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛 阅读详情

     好神的线段树题,以前只会维护区间什么数值信息的,竟然还可以维护联通性,好题啊,涨姿势了。。

    由于只有两行嘛,要保证线段树节点有可加性,我们维护六个信息,分别是右上到右下,右上到左上,右上到左下,右下到左上,右下到左下,左上到左下的联通性,合并的时候自己YY一下,还是很好想的。一点要注意的,父节点的左上到左下不能简单的直接把左儿子的值赋上去,还有可能是左走到右再走回来,右上右下的同理。。然后就是获取答案的时候,不一定就是在[L,R]这个区间里走,有可能会出现像R向右绕一个弯再走过去这样的情况,所以要把[1,L][L,R][R,n]三个区间的联通性都获取。。细节还是很多的。。

#include<cstdio>
#include<iostream>
#include<memory.h>
#define lc x*2
#define rc x*2+1
#define N 400405
using namespace std;
int n,x1,y1,x2,y2,qd,ans,ansl,ansr;
bool l12[N],r12[N],lr1[N],lr2[N],l1r2[N],l2r1[N],a[N][2][2];//a数组0向下1向右 
char s[10];
void build(int x,int l,int r)
{
	if (l==r)
	{
		lr1[x]=lr2[x]=true;
		return;
	}
	build(lc,l,(l+r)>>1);build(rc,(l+r)/2+1,r);
}
void update(int x,int mid,int lcc,int rcc)
{
	l12[x]=l12[lcc]||(lr1[lcc]&&a[mid][0][1]&&l12[rcc]&&a[mid][1][1]&&lr2[lcc]);
	r12[x]=r12[rcc]||(lr1[rcc]&&a[mid][0][1]&&r12[lcc]&&a[mid][1][1]&&lr2[rcc]);
	lr1[x]=(lr1[lcc]&&a[mid][0][1]&&lr1[rcc])||(l1r2[lcc]&&a[mid][1][1]&&l2r1[rcc]);
	lr2[x]=(lr2[lcc]&&a[mid][1][1]&&lr2[rcc])||(l2r1[lcc]&&a[mid][0][1]&&l1r2[rcc]);
	l1r2[x]=(lr1[lcc]&&a[mid][0][1]&&l1r2[rcc])||(l1r2[lcc]&&a[mid][1][1]&&lr2[rcc]);
	l2r1[x]=(lr2[lcc]&&a[mid][1][1]&&l2r1[rcc])||(l2r1[lcc]&&a[mid][0][1]&&lr1[rcc]);
}
void change(int x,int l,int r,int x1,int y1,int x2,int y2,bool k)
{
	int mid=(l+r)/2;
	if (y1==y2) 
	{
		if (l==r) 
		{
			a[y1][0][0]=k;
			l12[x]=r12[x]=l1r2[x]=l2r1[x]=k;
			return;
		}
		if (y1<=mid) change(lc,l,mid,x1,y1,x2,y2,k);else change(rc,mid+1,r,x1,y1,x2,y2,k);
		update(x,mid,lc,rc);
	}
	else
	{
		a[y1][x1][1]=k;
		if (mid==y1&&mid+1==y2) update(x,mid,lc,rc);
		else
		{
			if (mid>=y2) change(lc,l,mid,x1,y1,x2,y2,k);else change(rc,mid+1,r,x1,y1,x2,y2,k);
			update(x,mid,lc,rc);
		}
	}
}
int query(int x,int l,int r,int y1,int y2)
{
	if (y1<=l&&y2>=r) return x;
	int mid=(l+r)>>1;
	if (y2<=mid) return query(lc,l,mid,y1,y2);
	else if (y1>mid) return query(rc,mid+1,r,y1,y2);
	else
	{
		int ans=++qd,lcc=query(lc,l,mid,y1,mid),rcc=query(rc,mid+1,r,mid+1,y2);
		update(ans,mid,lcc,rcc);
		return ans;
	}
}
int main()
{
	freopen("1018.in","r",stdin);
//	freopen("1018.out","w",stdout);
	scanf("%d",&n);
	memset(a,0,sizeof(a));
	memset(l12,0,sizeof(l12));memset(r12,0,sizeof(r12));
	memset(lr1,0,sizeof(lr1));memset(lr2,0,sizeof(lr2));
	memset(l2r1,0,sizeof(l2r1));memset(l1r2,0,sizeof(l1r2));
	build(1,1,n);
	int t=1;
	while (t++)
	{
		scanf("%s",&s);
		if (s[0]=='E') return 0;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		if (y1>y2) swap(y1,y2),swap(x1,x2);	
		x1--;x2--;
		if (s[0]=='O') change(1,1,n,x1,y1,x2,y2,true);
		else if (s[0]=='C') change(1,1,n,x1,y1,x2,y2,false);
		else 
		{
			qd=400000;
			ans=query(1,1,n,y1,y2);ansl=query(1,1,n,1,y1);ansr=query(1,1,n,y2,n);
			if ((x1==0&&x2==0&&(lr1[ans]||(r12[ansl]&&l2r1[ans])||(l12[ansr]&&l1r2[ans])||(r12[ansl]&&l12[ansr]&&lr2[ans])))||(x1==1&&x2==1&&(lr2[ans]||(r12[ansl]&&l1r2[ans])||(l12[ansr]&&l2r1[ans])||(r12[ansl]&&l12[ansr]&&lr1[ans])))||(x1==0&&x2==1&&(l1r2[ans]||(r12[ansl]&&lr2[ans])||(l12[ansr]&&lr1[ans])))||(x1==1&&x2==0&&(l2r1[ans]||(r12[ansl]&&lr1[ans])||(l12[ansr]&&lr2[ans])))) printf("Y\n"); 
			else printf("N\n");
		}
	}
}


bzoj千题计划108:bzoj1018: [SHOI2008]堵塞交通traffic http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 用b数组表示 节点第0/1行的最右一列是否连接了右边 来 辅助 节点的合并 查询 对两个点位于矩形的位置分4种情况讨论 两点是否联通,要考虑四种情况 (以两个位置是矩形左... 阅读详情

相关推荐

bzoj1018 [SHOI2008]堵塞交通traffic

题目链接 分析: 这道题的题解很长,所以就不粘题面了,我们一点一点讲明白这道题 很荣幸,我看了题面之后 想到了这道题 可以很高兴的发现10w是线段树能够承受的范围 我们可以利用线段树维护连通性,每个节点内我们要维护6个信息,分别表示连通性: 读入完成后,我们面临的第一个问题就是道路的状态改变 这就牵扯到了一个change函数 在l...

weixin_30408165的博客 150

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

bzoj-1018 SHOI-2008 堵塞交通traffic 参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html 题目大意:有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C...

weixin_30673715的博客 99

bzoj一句话题解

bzoj一句话题解 by wawawa8 1000 a+b 1001 平面图最小割->对偶图最短路 1002 就是生成树个数,通过基尔霍夫矩阵可以得出递推式 \(f_i=3f_{i-1}-f_{i-2}+2\),然后高精度算一下 1003 令 \(c[i][j]\) 表示从第 \(i\) 天到第 \(j\) 天从 \(1\) 到 \(n\) 不转换路线的最短距离,然后 \(f[i]...

aozhuan8489的博客 305

BZOJ 1018 SHOI2008 堵塞交通traffic 线段树

题目大意:给定一张2*n的网格图,多次改变某条边是否可用,多次查询某两个点是否联通 多(yi)年前的我看到这题的第一反应是:这题尼玛能做? 两个点之间的路径可能是这样的: 也可能是这样的: 甚至可能是这样的: 这题能写? 这题其实好写爆了 我们首先忽略第三种情况,假设所有对答案有贡献的边都在两个点的中间 那么我们以每一列为一个叶节点建

世界 2783

BZOJ1018】[SHOI2008]堵塞交通traffic 线段树

BZOJ1018】[SHOI2008]堵塞交通traffic Description   有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道...

aodanchui1057的博客 132

[bzoj1018][SHOI2008]堵塞交通traffic【线段树

【题目描述】Description  有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,...

dizhengyue1902的博客 134

BZOJ1018】【SHOI2008堵塞交通traffic(线段树)(好题)

Description  有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交

(■-■) 498

bzoj1018】[SHOI2008]堵塞交通traffic 线段树维护连通性

Description有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交通部某份差事,部

DQS的树洞 1007

BZOJ1018 | SHOI2008-堵塞交通traffic——线段树维护区间连通性+细节

【题目描述】 BZOJ1018 | SHOI2008-堵塞交通traffic  有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵...

T_T233333333的博客 317

BZOJ】【P1018】【SHOI2008】【堵塞交通traffic】【题解】【线段树

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1018 分类讨论到吐 Code: #include using namespace std; const int maxn=1e5+5; int a[maxn],b[maxn],c[maxn],n;//a上方,b下方,c中间 int getint(){ int res=0;char

退役狗的专栏 1259

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

题目描述   有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交通部某份差事,部...

weixin_30430169的博客 108

BZOJ1018】[SHOI2008]堵塞交通

BZOJ1018】[SHOI2008]堵塞交通 题面 bzoj 洛谷 洛谷 题解 菊队讲要用线段树维护连通性,但是好像没人写 解法一 将所有的加边删边离线,然后以最近删除时间为边权,$LCT$维护最大生成树即可 代码 #include <iostream> #include <cstdio> #include <cstdlib...

123

BZOJ[1018][SHOI2008]堵塞交通traffic 线段树

传送门ber~ 哇这个线段树好神啊!! 用线段树维护图连通性,每个节点开个二维数组ai,jai,ja_{i,j}表示这个区间最左面的第iii行能不能走到最右面的第jjj行,同时记录一下最左最右第一行与第二行是否都能互相走到 这六个东西可以用线段树维护啊(看代码)! 细节有点多…具体看代码吧… 注释说的很清楚(自信) 代码如下: #include&lt;algorithm&gt; #i...

谁能代表肯德基 531

BZOJ 1018|SHOI 2008|堵塞交通|线段树

咦,一道自带题解的题目?题目的坐标表示成(r,c),r=row,行号,c=column,列号。 因此x1,x2只有取1和2两种情况………考虑线段树维护一格的连通性,合并区间如图: 令总的为r,左半区间a,右半区间b,修改了mid(x,y)。 那么对于r0(上);r1(下);r2(左);r3(右);r4(右下);r5(右上)r_0(上);r_1(下);r_2(左);r_3(右);r_4(右下

とある黄鱼のOIブログ 848
上一篇: [BZOJ2618]CQOI2006凸多边形|扫描线
下一篇: [BZOJ1787]AHOI2008 紧急集合|LCA
Tag_king
博客等级 码龄12年 15粉丝 164原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值