BZOJ_1018_[JSOI2008]_交通堵塞traffic_(线段树)

描述



http://www.lydsy.com/JudgeOnline/problem.php?id=1018

\(2*n\)的距形,起初没有边相连,之后有三种操作:

1.加边.

2.删边.

3.询问某两个点是否联通.

分析



这题太神了...

用线段树维护连通性...

放弃解释清楚了...

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 const int maxn=1e5+5;
  5 int n,cnt;
  6 char s[10];
  7 bool A[maxn][2];
  8 struct node{
  9     bool a[2][2];
 10     node(){
 11         a[0][0]=a[0][1]=a[1][0]=a[1][1]=false;
 12     }
 13     bool* operator [] (int id){return a[id];}
 14 }a[maxn<<4];
 15 struct Segment_tree{
 16     node merge(bool *a,node x,node y){
 17         node t;
 18         t[0][0]=(x[0][0]&a[0]&y[0][0])|(x[0][1]&a[1]&y[1][0]);
 19         t[0][1]=(x[0][0]&a[0]&y[0][1])|(x[0][1]&a[1]&y[1][1]);
 20         t[1][0]=(x[1][0]&a[0]&y[0][0])|(x[1][1]&a[1]&y[1][0]);
 21         t[1][1]=(x[1][1]&a[1]&y[1][1])|(x[1][0]&a[0]&y[0][1]);
 22         return t;
 23     }
 24     void build_tree(int l,int r,int k){
 25         if(l==r){a[k][0][0]=a[k][1][1]=true;return;}
 26         int mid=l+(r-l)/2;
 27         build_tree(l,mid,k<<1); build_tree(mid+1,r,k<<1|1);
 28     }
 29     void update(int l,int r,int k,int pos,bool op,bool dir){
 30         if(l==r){
 31             if(dir) a[k][0][1]=a[k][1][0]=op;//c
 32             return;
 33         }
 34         int mid=l+(r-l)/2;
 35         if(!dir&&pos==mid){//r
 36             a[k]=merge(A[mid],a[k<<1],a[k<<1|1]);
 37             return;
 38         }
 39         if(pos<=mid) update(l,mid,k<<1,pos,op,dir);
 40         else update(mid+1,r,k<<1|1,pos,op,dir);
 41         a[k]=merge(A[mid],a[k<<1],a[k<<1|1]);
 42     }
 43     void _get_right(int l,int r,int k,int &pos,node &t,bool dir){
 44         if(l==r) return;
 45         int mid=l+(r-l)/2;
 46         node tmp=merge(A[l-1],t,a[k<<1]);
 47         if(tmp[dir][0]||tmp[dir][1]) pos=mid, t=tmp, _get_right(mid+1,r,k<<1|1,pos,t,dir);
 48         else _get_right(l,mid,k<<1,pos,t,dir);
 49     }
 50     void _get_left(int l,int r,int k,int &pos,node &t,bool dir){
 51         if(l==r) return;
 52         int mid=l+(r-l)/2;
 53         node tmp=merge(A[r],a[k<<1|1],t);
 54         if(tmp[0][dir]||tmp[1][dir]) pos=mid+1,t=tmp, _get_left(l,mid,k<<1,pos,t,dir);
 55         else _get_left(mid+1,r,k<<1|1,pos,t,dir);
 56     }
 57     void get_right(int l,int r,int k,int &pos,node &t,bool dir){
 58         if(l==r) {t=a[k];return;}
 59         int mid=l+(r-l)/2;
 60         if(pos>mid) get_right(mid+1,r,k<<1|1,pos,t,dir);
 61         else{
 62             get_right(l,mid,k<<1,pos,t,dir);
 63             if(pos!=mid) return;
 64             node tmp=merge(A[mid],t,a[k<<1|1]);
 65             if(tmp[dir][0]||tmp[dir][1]) pos=r,t=tmp;
 66             else _get_right(mid+1,r,k<<1|1,pos,t,dir);
 67         }
 68     }
 69     void get_left(int l,int r,int k,int &pos,node &t,bool dir){
 70         if(l==r) {t=a[k];return;}
 71         int mid=l+(r-l)/2;
 72         if(pos<=mid) get_left(l,mid,k<<1,pos,t,dir);
 73         else{
 74             get_left(mid+1,r,k<<1|1,pos,t,dir);
 75             if(pos!=mid+1) return;
 76             node tmp=merge(A[mid],a[k<<1],t);
 77             if(tmp[0][dir]||tmp[1][dir]) pos=l,t=tmp;
 78             else _get_left(l,mid,k<<1,pos,t,dir);
 79         }
 80     }
 81     node get_ans(int l,int r,int k,int x,int y){
 82         if(l==x&&r==y) return a[k];
 83         int mid=l+(r-l)/2;
 84         if(y<=mid) return get_ans(l,mid,k<<1,x,y);
 85         if(x>mid) return get_ans(mid+1,r,k<<1|1,x,y);
 86         return merge(A[mid],get_ans(l,mid,k<<1,x,mid),get_ans(mid+1,r,k<<1|1,mid+1,y));
 87     }
 88 }t;
 89 void update(int x1,int y1,int x2,int y2,bool op){
 90     if(x1==x2){//r
 91         if(y1>y2) swap(y1,y2);
 92         A[y1][x1]=op;
 93         t.update(1,n,1,y1,op,false);
 94     }
 95     else t.update(1,n,1,y1,op,true);//c
 96 }
 97 void query(int x1,int y1,int x2,int y2){
 98     if(y1>y2) swap(x1,x2), swap(y1,y2);
 99     node tmp1;
100     t.get_left(1,n,1,y1,tmp1,x1);
101     x1=tmp1[0][x1]?0:1;
102     node tmp2;
103     t.get_right(1,n,1,y2,tmp2,x2);
104     x2=tmp2[x2][0]?0:1;
105     node tmp=t.get_ans(1,n,1,y1,y2);
106     puts(tmp[x1][x2]?"Y":"N");
107
108 }
109 int main(){
110     int x1,y1,x2,y2;
111     scanf("%d",&n);
112     t.build_tree(1,n,1);
113     while(true){
114         scanf("%s",s);
115         if(s[0]==‘C‘) scanf("%d%d%d%d",&x1,&y1,&x2,&y2), update(x1-1,y1,x2-1,y2,false);
116         else if(s[0]==‘O‘) scanf("%d%d%d%d",&x1,&y1,&x2,&y2), update(x1-1,y1,x2-1,y2,true);
117         else if(s[0]==‘A‘) scanf("%d%d%d%d",&x1,&y1,&x2,&y2), query(x1-1,y1,x2-1,y2);
118         else if(s[0]==‘E‘) break;
119     }
120     return 0;
121 }

1018: [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit: 162 MB
Submit: 2747  Solved: 914
[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

HINT

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

Source

时间: 2024-10-13 11:40:59

BZOJ_1018_[JSOI2008]_交通堵塞traffic_(线段树)的相关文章

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

Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵解决,道路才会恢复畅通.初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度 发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入

[BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经典模型. 我们线段树的一个节点表示一个区间的联通性,有 6 个 bool 值,表示这个区间的 4 个角上的点之间的联通性. 然后用两个子区间的联通性和两个子区间之间的连边情况合并出整个区间的联通性. 修改某条边时,先在边的数组中修改,然后从这条边所在的点的线段树叶子开始向上 Update . 询问两

BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 4750  Solved: 2145[Submit][Status][Discuss] Description 现 在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一

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

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3064  Solved: 1027[Submit][Status][Discuss] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通

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

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

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

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

BZOJ 1018 SHOI2008 堵塞的交通traffic 线段树

题目大意:给定一张2*n的网格图,多次改变某条边是否可用,多次查询某两个点是否联通 多(yi)年前的我看到这题的第一反应是:这题尼玛能做? 两个点之间的路径可能是这样的: 也可能是这样的: 甚至可能是这样的: 这题能写? 这题其实好写爆了 我们首先忽略第三种情况,假设所有对答案有贡献的边都在两个点的中间 那么我们以每一列为一个叶节点建立线段树 线段树的每个节点开一个二维数组a[2][2] 其中 a[x][y]记录当前区间的左端点的第x行和右端点的第y行是否联通 那么合并如下: 例如,a[0][0

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

线段树维护每一块左上到左下.右上到右下.左上到右上.左下到右下.左上到右下.左下到右上的联通情况. #include<bits/stdc++.h> #define N 100005 #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define K l,r,k #define L l,M,P #define R M+1,r,S #define Z int l=1,int r=n,int k=1 u

数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic

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