博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ_1018_[SHOI2008]_交通堵塞traffic_(线段树)
阅读量:5303 次
发布时间:2019-06-14

本文共 5381 字,大约阅读时间需要 17 分钟。

描述


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

1.加边.

2.删边.

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

 

分析


这题太神了...

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

放弃解释清楚了...

 

 

1 #include 
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 }
View Code

 

1018: [SHOI2008]堵塞的交通traffic

Time Limit: 3 Sec  Memory Limit: 162 MB
Submit: 2747  Solved: 914
[][][]

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

 题解:

Source

转载于:https://www.cnblogs.com/Sunnie69/p/5647746.html

你可能感兴趣的文章
Lua_02
查看>>
ios蓝牙详解
查看>>
安装MySQL5.7.18遇到的坑
查看>>
React Native在Android平台运行gif的解决方法转载
查看>>
Mybatis RowBounds 是逻辑分页
查看>>
hdu 3341(ac自动机+状态压缩)
查看>>
51单片机之蓝牙遥控小车_效果展示+单片机知识+完整蓝牙电车代码
查看>>
Sql Server中REPLACE函数的使用
查看>>
SqlServerl的行转列
查看>>
JavaScript跨域总结与解决办法
查看>>
Hover功能
查看>>
[LeetCode] Jump Game II
查看>>
js千分位处理
查看>>
js常用的方法
查看>>
Mac---------三指拖移
查看>>
关于VMare中安装Ubuntu的一些说明
查看>>
七、K3 WISE 开发插件《工业单据老单插件中获取登陆用户名》
查看>>
字符串类型的相互转换
查看>>
图片编辑的利器(介绍韩国免费图片工具PhotoScape)
查看>>
Python基础第十一天:递归函数
查看>>