zoukankan      html  css  js  c++  java
  • BZOJ 1018 堵塞的交通 线段树维护连通性

    $ Rightarrow $ 戳我进BZOJ原题

    [SHOI2008]堵塞的交通traffic

    Time Limit: 3 Sec $ quad $ Memory Limit: 162 MB
     

    Description

    有一天,由于某种穿越现象作用,你来到了传说中的小人国。
    小人国的布局非常奇特,整个国家的交通系统可以被看成是一个$ 2 $ 行 $ C $ 列的矩形网格,
    网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有 $ 2 imes C $个城市和 $ 3 imes C−2 $ 条道路。

    小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通。
    初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度发达的世界,
    喜出望外地要求你编写一个查询应答系统,以挽救已经病入膏肓的小人国交通系统。
    小人国的交通部将提供一些交通信息给你,你的任务是根据当前的交通情况回答查询的问题。交通信息可以分为以下几种格式:

    • Close r1 c1 r2 c2:相邻的两座城市 $ (r_1,c_1) $ 和 $ (r_2, c_2 ) $ 之间的道路被堵塞了;
    • Open r1 c1 r2 c2:相邻的两座城市 $ (r_1, c_1) $ 和 $ (r_2, c_2) $ 之间的道路被疏通了;
    • Ask r1 c1 r2 c2:询问城市$ (r_1, c_1) $ 和 $ (r_2, c_2) $ 是否连通。如果存在一条路径使得这两条城市连通,则返回Y,否则返回N。

    注:$ r_i $ 表示行数,$ c_i $ 表示列数,$ 1≤ri≤2,1≤ci≤C1 leq r_i leq 2, 1 leq c_i leq C $ 。
     

    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
    

     

    HINT

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

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 200005
    inline int read() {
        register char ch;
        while(!isdigit(ch=getchar()));
        register int x=ch^'0';
        while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
        return x;
    }
    int n;
    char opt[5];
    struct tree{ bool e[3][3]; }t[N<<2];
    int a[N<<2][2];
    void build(int o,int l,int r){
    	if(l==r){
    		t[o].e[0][0]=t[o].e[1][1]=1;
    		return;
    	}
    	int mid=l+r>>1;
    	build(o<<1,l,mid); build(o<<1|1,mid+1,r);
    }
    void pushup(int o,int l,int r){
    	if(l==r) return;
    	int L=o<<1,R=o<<1|1,mid=l+r>>1;
    	t[o].e[0][0] = (t[L].e[0][0] && t[R].e[0][0] && a[mid][0]) || (t[L].e[0][1] && t[R].e[1][0] && a[mid][1]);
    	t[o].e[0][1] = (t[L].e[0][0] && t[R].e[0][1] && a[mid][0]) || (t[L].e[0][1] && t[R].e[1][1] && a[mid][1]);
    	t[o].e[1][0] = (t[L].e[1][0] && t[R].e[0][0] && a[mid][0]) || (t[L].e[1][1] && t[R].e[1][0] && a[mid][1]);
    	t[o].e[1][1] = (t[L].e[1][0] && t[R].e[0][1] && a[mid][0]) || (t[L].e[1][1] && t[R].e[1][1] && a[mid][1]);
    	t[o].e[2][0] = t[L].e[2][0] || (t[o].e[0][1] && t[o].e[1][1]) || (t[o].e[0][0] && t[o].e[1][0]) || (t[o].e[0][0] && t[o].e[1][1] && t[R].e[2][1]) || (t[L].e[0][0] && t[L].e[1][1] && t[R].e[2][0] && a[mid][0] && a[mid][1]);
    	t[o].e[2][1] = t[R].e[2][1] || (t[o].e[0][0] && t[o].e[0][1]) || (t[o].e[1][0] && t[o].e[1][1]) || (t[o].e[0][0] && t[o].e[1][1] && t[L].e[2][0]) || (t[R].e[0][0] && t[R].e[1][1] && t[L].e[2][1] && a[mid][0] && a[mid][1]);
    }
    void updata_row(int o,int l,int r,int x,int p){
    	//p==1 : open	p==0 : close
    	if(l==r){
    		t[o].e[0][0]=t[o].e[1][1]=1;
    		t[o].e[1][0]=t[o].e[0][1]=t[o].e[2][0]=t[o].e[2][1]=p;
    		return;
    	}
    	int mid=l+r>>1;
    	if(x>mid) updata_row(o<<1|1,mid+1,r,x,p);
    	else updata_row(o<<1,l,mid,x,p);
    	pushup(o,l,r);
    }
    void updata_column(int o,int l,int r,int x,int c,int p){
    	//p==1 : open	p==0 : close
    	if(l==r){
    		a[x][c]=p;
    		return;
    	}
    	int mid=l+r>>1;
    	if(x>mid) updata_column(o<<1|1,mid+1,r,x,c,p);
    	else updata_column(o<<1,l,mid,x,c,p);
    	pushup(o,l,r);
    }
    void work(int c1,int r1,int c2,int r2,int p){
    	//p==1 : open	p==0 : close
    	if(c1==c2) updata_row(1,1,n,c1,p);
    	else {
    		if(c1>c2) swap(c1,c2);
    		if( (!a[c1][r1] && p==1) || (a[c1][r1] && p==0) )
    			updata_column(1,1,n,c1,r1,p);
    	}
    }
    tree query_direct(int o,int l,int r,int L,int R){
    	if(L==l&&r==R) return t[o];
    	int mid=l+r>>1;
    	if(L>mid) return query_direct(o<<1|1,mid+1,r,max(mid+1,L),R);
    	else if(R<=mid) return query_direct(o<<1,l,mid,L,min(mid,R));
    	else {
    		tree res,tL,tR;
    		tL=query_direct(o<<1,l,mid,L,min(mid,R));
    		tR=query_direct(o<<1|1,mid+1,r,max(mid+1,L),R);
    		res.e[0][0] = (tL.e[0][0] && tR.e[0][0] && a[mid][0]) || (tL.e[0][1] && tR.e[1][0] && a[mid][1]);
    		res.e[0][1] = (tL.e[0][0] && tR.e[0][1] && a[mid][0]) || (tL.e[0][1] && tR.e[1][1] && a[mid][1]);
    		res.e[1][0] = (tL.e[1][0] && tR.e[0][0] && a[mid][0]) || (tL.e[1][1] && tR.e[1][0] && a[mid][1]);
    		res.e[1][1] = (tL.e[1][0] && tR.e[0][1] && a[mid][0]) || (tL.e[1][1] && tR.e[1][1] && a[mid][1]);
    		res.e[2][0] = tL.e[2][0] || (res.e[0][1] && res.e[1][1]) || (res.e[0][0] && res.e[1][0]) || (res.e[0][0] && res.e[1][1] && tR.e[2][1]) || (tL.e[0][0] && tL.e[1][1] && tR.e[2][0] && a[mid][0] && a[mid][1]);
    		res.e[2][1] = tR.e[2][1] || (res.e[0][0] && res.e[0][1]) || (res.e[1][0] && res.e[1][1]) || (res.e[0][0] && res.e[1][1] && tL.e[2][0]) || (tR.e[0][0] && tR.e[1][1] && tL.e[2][1] && a[mid][0] && a[mid][1]);
    		return res;
    	}
    }
    bool query(int c1,int r1,int c2,int r2){
    	if(c1>c2){ 
    		swap(c1,c2); 
    		swap(r1,r2); 
    	}
    	tree tmp=query_direct(1,1,n,c1,c2);
    	if(tmp.e[r1][r2]) return 1;
    	tree L=query_direct(1,1,n,1,c1);
    	tree R=query_direct(1,1,n,c2,n);
    	if(L.e[2][1] && tmp.e[r1^1][r2]) return 1;
    	if(R.e[2][0] && tmp.e[r1][r2^1]) return 1;
    	if(L.e[2][1] && R.e[2][0] && tmp.e[r1^1][r2^1]) return 1;
    	return 0;
    }
    int main(){
    	n=read();
    	build(1,1,n);
    	while(1){
    		scanf("%s",opt);
    		if(opt[0]=='E') break;
    		int r1,c1,r2,c2;
    		r1=read()-1; c1=read(); r2=read()-1; c2=read();
    		if(opt[0]=='O') work(c1,r1,c2,r2,1);
    		if(opt[0]=='C') work(c1,r1,c2,r2,0);
    		if(opt[0]=='A') query(c1,r1,c2,r2) ? puts("Y") : puts("N");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Redis做为缓存的几个问题
    Python——操作smb文件服务器(上传和下载)
    Python——assert、isinstance的用法
    centos7-修改默认python为3
    mqtt
    如何编译生成 mkfs.ubifs、ubinize 工具
    2020-2笔记
    2020-1笔记
    C语言中getopt()和getopt_long()函数的用法
    buildroot
  • 原文地址:https://www.cnblogs.com/PotremZ/p/BZOJ1018.html
Copyright © 2011-2022 走看看