[BZOJ1018]堵塞的交通traffic
阿新 • • 發佈:2018-08-28
聯通 idt ios script query https inf tree des 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;
Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
N
Description
有一天,由於某種穿越現象作用,你來到了傳說中的小人國。小人國的布局非常奇特,整個國家的交通系統可
以被看成是一個2行C列的矩形網格,網格上的每個點代表一個城市,相鄰的城市之間有一條道路,所以總共有2C個
城市和3C-2條道路。 小人國的交通狀況非常槽糕。有的時候由於交通堵塞,兩座城市之間的道路會變得不連通,
直到擁堵解決,道路才會恢復暢通。初來咋到的你決心毛遂自薦到交通部某份差事,部長聽說你來自一個科技高度
發達的世界,喜出望外地要求你編寫一個查詢應答系統,以挽救已經病入膏肓的小人國交通系統。 小人國的交通
部將提供一些交通信息給你,你的任務是根據當前的交通情況回答查詢的問題。交通信息可以分為以下幾種格式:
市(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 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
Sample Output
YN
HINT
題解:JudgeOnline/upload/201604/sol(4).rar
Source
麻煩的一批。先找出一共有幾種情況要維護,尤其是不要漏掉先往外走再往裏走的蛇皮走位
如果直接去維護某兩點之間的路徑是什麽,是沒法維護的。事實上兩點之間不管是經歷了怎樣蛇皮的走位走過來,與我們都無關,我們要維護的只是兩點是否聯通。對於相鄰兩列四個點,如圖,一共有六種路徑,我們需要維護它們。而如何向上合並呢?我們還要維護兩個兒子之間是否聯通。這些想清楚了剩下的反而簡單了,對著圖慢慢打就行啦~
代碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define ls node*2 5 #define rs node*2+1 6 #define M 100010 7 using namespace std; 8 struct Tree 9 { 10 bool l,r;//上下 11 bool s1,s2;//左上->右上,左下->右下 12 bool s3,s4;//左上->右下,左下->右上 13 bool half1,half2;//l,r重點M和M+1之間的連通性 14 }tr[M<<2]; 15 16 void build(int node,int l,int r) 17 { 18 if(l==r) 19 { 20 tr[node].half1=tr[node].half2=1; 21 tr[node].s1=tr[node].s2=1; 22 return; 23 } 24 int mid=(l+r)/2; 25 build(ls,l,mid); 26 build(rs,mid+1,r); 27 } 28 29 void update(Tree &now,Tree L,Tree R) 30 { 31 now.l=L.l | (L.s1 & L.s2 & now.half1 & now.half2 & R.l); 32 now.r=R.r | (R.s1 & R.s2 & now.half1 & now.half2 & L.r); 33 now.s1=(L.s1 & R.s1 & now.half1) | (L.s3 & R.s4 & now.half2); 34 now.s2=(L.s2 & R.s2 & now.half2) | (L.s4 & R.s3 & now.half1); 35 now.s3=(L.s3 & R.s2 & now.half2) | (L.s1 & R.s3 & now.half1); 36 now.s4=(L.s4 & R.s1 & now.half1) | (L.s2 & R.s4 & now.half2); 37 } 38 39 void changer(int node,int l,int r,int ud,int k,int val) 40 { 41 int mid=(l+r)/2; 42 if(mid==k) 43 { 44 if(ud==1) tr[node].half1=val; 45 else tr[node].half2=val; 46 update(tr[node],tr[ls],tr[rs]); 47 return; 48 } 49 if(k<=mid) changer(ls,l,mid,ud,k,val); 50 else changer(rs,mid+1,r,ud,k,val); 51 update(tr[node],tr[ls],tr[rs]); 52 } 53 54 void changec(int node,int l,int r,int k,int val) 55 { 56 if(l==r) 57 { 58 tr[node].s3=tr[node].s4=val; 59 tr[node].l=tr[node].r=val; 60 return; 61 } 62 int mid=(l+r)/2; 63 if(k<=mid) changec(ls,l,mid,k,val); 64 else changec(rs,mid+1,r,k,val); 65 update(tr[node],tr[ls],tr[rs]); 66 } 67 68 Tree query(int node,int l,int r,int l1,int r1) 69 { 70 int mid=(l+r)/2; 71 if(l1<=l&&r1>=r) return tr[node]; 72 if(r1<=mid) return query(ls,l,mid,l1,r1); 73 else if(l1>mid) return query(rs,mid+1,r,l1,r1); 74 else 75 { 76 Tree res=tr[node]; 77 update(res,query(ls,l,mid,l1,r1),query(rs,mid+1,r,l1,r1)); 78 return res; 79 } 80 } 81 82 int main() 83 { 84 int n; 85 scanf("%d",&n); build(1,1,n); 86 while(1) 87 { 88 char s[10]; 89 int r1,r2,c1,c2; 90 scanf("%s",s); 91 if(s[0]==‘E‘) break; 92 scanf("%d%d%d%d",&r1,&c1,&r2,&c2); 93 if(c1>c2) swap(c1,c2),swap(r1,r2); 94 if(s[0]==‘O‘) 95 { 96 if(r1==r2) changer(1,1,n,r1,c1,1); 97 else changec(1,1,n,c1,1); 98 } 99 else if(s[0]==‘C‘) 100 { 101 if(r1==r2) changer(1,1,n,r1,c1,0); 102 else changec(1,1,n,c1,0); 103 } 104 else 105 { 106 Tree l=query(1,1,n,1,c1),x=query(1,1,n,c1,c2),r=query(1,1,n,c2,n); 107 bool flag; 108 if(r1==1 && r2==1) flag=x.s1 | (l.r & x.s4) | (r.l & x.s3) | (l.r & r.l & x.s2); 109 if(r1==2 && r2==2) flag=x.s2 | (l.r & x.s3) | (r.l & x.s4) | (l.r & r.l & x.s1); 110 if(r1==1 && r2==2) flag=x.s3 | (l.r & x.s2) | (r.l & x.s1) | (l.r & r.l & x.s4); 111 if(r1==2 && r2==1) flag=x.s4 | (l.r & x.s1) | (r.l & x.s2) | (l.r & r.l & x.s3); 112 puts(flag?"Y":"N"); 113 } 114 } 115 return 0; 116 }
[BZOJ1018]堵塞的交通traffic