首页 > 学院 > 开发设计 > 正文

bzoj 1018: [SHOI2008]堵塞的交通traffic (线段树维护连通性)

2019-11-08 01:41:57
字体:
来源:转载
供稿:网友

1018: [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3192  Solved: 1062[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

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

Sample Output

YN

HINT

 题解:JudgeOnline/upload/201604/sol(4).rar

Source

[Submit][Status][Discuss]

题解:线段树维护连通性

对于相邻两个点维护6个信息。

需要注意的是查询的时候,该区间的r1,r2不连通,不一定r1,r2无法连通,所以需要考虑通过两边的区间使r1,r2连通的情况。

还有对于单点的修改,所有的值都要重新计算。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define N 100003using namespace std;int n;struct data {	int l1,l2,h1,h2,r1,r2;//l1,l2,r1,r2是真实存在的,h1,h2每次更改都需要重新推 	data() {		l1=l2=h1=h2=r1=r2=0;	}}tr[N*4],a[N];//l1表示左上角到右上角//l2表示左下角到右下角 //r1表示左上角到左下角 //r2表示右上角到右下角 //h1表示左上角到右下角 //h2表示左下角到右上角 data update(data a,data b){	data t;	t.l1=max(t.l1,a.l1&b.l1); t.l1=max(t.l1,a.h1&b.h2); 	t.l2=max(t.l2,a.l2&b.l2); t.l2=max(t.l2,a.h2&b.h1);	t.r1=a.r1; t.r1=max(t.r1,t.l1&t.l2&b.r2); t.r1=max(t.r1,a.l1&b.r1&a.l2);	t.r2=b.r2; t.r2=max(t.r2,t.l1&t.l2&a.r1); t.r2=max(t.r2,b.l1&b.l2&a.r2);	t.h1=max(t.h1,a.l1&b.h1); t.h1=max(t.h1,a.h1&b.l2);	t.h2=max(t.h2,a.h2&b.l1); t.h2=max(t.h2,a.l2&b.h2);	return t;}void pointchange(int now,int l,int r,int opt,int x,int val)//opt=1 l1;opt=2 l2; opt=3 r1;opt=4 r2;{	if (x==0) return;	if (l==r) {		tr[now].l1=a[l].l1;		tr[now].l2=a[l].l2;		tr[now].r1=a[l].r1;		tr[now].r2=a[l].r2;		tr[now].l1=max(tr[now].l1,tr[now].r1&tr[now].l2&tr[now].r2);		tr[now].l2=max(tr[now].l2,tr[now].r1&tr[now].l1&tr[now].r2);		tr[now].r1=max(tr[now].r1,tr[now].l1&tr[now].r2&tr[now].l2);		tr[now].r2=max(tr[now].r2,tr[now].l1&tr[now].r1&tr[now].l2);		tr[now].h1=max(tr[now].r1&tr[now].l2,tr[now].l1&tr[now].r2);		tr[now].h2=max(tr[now].r1&tr[now].l1,tr[now].l2&tr[now].r2);		return;	}	int mid=(l+r)/2;	if (x<=mid) pointchange(now<<1,l,mid,opt,x,val);	else pointchange(now<<1|1,mid+1,r,opt,x,val);	tr[now]=update(tr[now<<1],tr[now<<1|1]); }data query(int now,int l,int r,int ll,int rr){	data t;	if (rr<ll||!ll) return t;	if (ll<=l&&r<=rr) return tr[now];	int mid=(l+r)/2;  bool pd=false;	if (ll<=mid) t=query(now<<1,l,mid,ll,rr),pd=true;	if (rr>mid)  {		data a=query(now<<1|1,mid+1,r,ll,rr);		if (pd) t=update(t,a);		else t=a;	}	return t;}int main(){	freopen("a.in","r",stdin);	freopen("my.out","w",stdout);	scanf("%d",&n);	while (true) {		char s[10]; scanf("%s",s);		int x,y,x0,y0; scanf("%d%d%d%d",&x0,&y0,&x,&y);		if (y0>y) swap(x0,x),swap(y0,y);		if (s[0]=='E') break;		if(s[0]=='O'||s[0]=='C') {			int opt=0; int t=0; data t1;			if (s[0]=='O') t=1; 			if (x0==x&&x==1) opt=1,a[y0].l1=t,pointchange(1,1,n,1,y0,t);			if (x0==x&&x==2) opt=2,a[y0].l2=t,pointchange(1,1,n,2,y0,t);			if (y0==y){			  a[y].r1=t,pointchange(1,1,n,3,y,t);			  a[y-1].r2=t,pointchange(1,1,n,4,y-1,t);		    }		}		else {			int opt; data t,t1,t2; int pd=false;			if (x==x0&&y==y0) {				PRintf("Y/n");				continue;			}			if (x0==x&&x==1) {			  t1=query(1,1,n,1,y0-1);  t2=query(1,1,n,y,n);			  t=query(1,1,n,y0,y-1),pd=t.l1;			  t.r1=max(t.r1,t1.r2); t.r2=max(t.r2,t2.r1);			  pd=max(pd,t.r1&t.l2&t.r2);		    }			if (x0==x&&x==2){			  t=query(1,1,n,y0,y-1),pd=t.l2;			  t1=query(1,1,n,1,y0-1);  t2=query(1,1,n,y,n);			  t.r1=max(t.r1,t1.r2); t.r2=max(t.r2,t2.r1);			  pd=max(pd,t.r1&t.l1&t.r2);		    }			if (x0==1&&x==2&&y!=y0) {			  t=query(1,1,n,y0,y-1),pd=t.h1;			  t1=query(1,1,n,1,y0-1); t2=query(1,1,n,y,n);			  t.r1=max(t.r1,t1.r2); t.r2=max(t.r2,t2.r1);			  pd=max(pd,t.r1&t.l2); pd=max(pd,t.r2&t.l1);			  pd=max(pd,t.r1&t.h2&t.r2);		    }			if (x0==2&&x==1&&y!=y0) {			  t=query(1,1,n,y0,y-1),pd=t.h2;			  t1=query(1,1,n,1,y0-1);  t2=query(1,1,n,y,n);			  t.r1=max(t.r1,t1.r2); t.r2=max(t.r2,t2.r1);			  pd=max(pd,t.r1&t.l1); pd=max(pd,t.r2&t.l2);			  pd=max(pd,t.r1&t.h1&t.r2);		    }			if (x0!=x&&y==y0) {			 t1=query(1,1,n,1,y0-1);  t2=query(1,1,n,y,n); 			 pd=t1.r2|t2.r1;		    }		    if (pd) printf("Y/n");		    else printf("N/n");		}	}}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表