description
有一天,由於某種穿越現象作用,你來到了傳說中的小人國。小人國的布局非常奇特,整個國家的交通系統可以被看成是乙個
2 行
c列的矩形網格,網格上的每個點代表乙個城市,相鄰的城市之間有一條道路,所以總共有2c
個城市和3c
−2條道路。 小人國的交通狀況非常槽糕。有的時候由於交通堵塞,兩座城市之間的道路會變得不連通,直到擁堵解決,道路才會恢復暢通。初來咋到的你決心毛遂自薦到交通部某份差事,部長聽說你來自乙個科技高度發達的世界,喜出望外地要求你編寫乙個查詢應答系統,以挽救已經病入膏肓的小人國交通系統。 小人國的交通部將提供一些交通資訊給你,你的任務是根據當前的交通情況回答查詢的問題。交通資訊可以分為以下幾種格式:
close r1
c1
r2 c
2 :相鄰的兩座城市(r
1,c1
) 和(r
2,c2
) 之間的道路被堵塞了;
open r1
c1
r2 c
2 :相鄰的兩座城市(r
1,c1
) 和(r
2,c2
) 之間的道路被疏通了;
ask r1
c1
r2 c
2 :詢問城市(r
1,c1
) 和(r
2,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 outputy n
hint
題解:judgeonline/upload/201604/sol(4).rar
source
思路
首先對於乙個只有一行的情況,可以很容易的用線段樹維護。
但是對於兩行的情況,就需要用一些奇怪的技巧了。
考慮下面這個圖:
1,1 到r2
,2可以先從r1
,1到r2,
1 ,再到r1
,2,最後是r2
,2。
那麼可以維護r1
,1到r2,
1 的聯通性,r2
,1到r1,
2 的聯通性,r1
,2到r2,
2 的聯通性。
具體一點,假設有區間為:
q ———rz那麼需要維護———v
q ,r,
z ,
v這4個點兩兩之間的聯通性。
那麼更新時就通過這個更新,還有區間mi
d 到mi
d+1 的聯通性(第一列和第二列)就好了。
詢問就按照上面的查詢方法寫。
**
其實是可以不用寫這麼多的,只是我寫的太長了……
#include
#include
const
int maxn=100000;
struct data
;struct segment_tree
int build(int now,int left,int right)
//建樹
int mid=(left+right)>>1;
val[now].we=val[now].xc=0;
build(now<<1,left,mid);
build(now<<1|1,mid+1,right);
merge(val[now],val[now<<1],val[now<<1|1]);
return
0; }
int rchange(int now,int left,int right,int pos,int cval)
//將(1,pos)這個點與(2,pos)這個點的聯通性變成cval
int mid=(left+right)>>1;
if(pos<=mid)//尋找pos
else
merge(val[now],val[now<<1],val[now<<1|1]);//更新這個點的val
return
0; }
int uchange(int now,int left,int right,int pos,int cval)
//將(1,pos)這個點和(1,pos+1)這個點之間的聯通性修改為cval
if(pos<=mid)//尋找pos
else
merge(val[now],val[now<<1],val[now<<1|1]);
return
0; }
int dchange(int now,int left,int right,int pos,int cval)
//將(2,pos)這個點和(2,pos+1)這個點的聯通性修改為cval
if(pos<=mid)//尋找pos
else
merge(val[now],val[now<<1],val[now<<1|1]);//更新這個點的val
return
0; }
data query(int now,int left,int right,int s,int t)
//詢問s到t區間的聯通性(用乙個data表示)
int mid=(left+right)>>1;
if(s>mid)
else
if(t<=mid)
else
}};segment_tree st;
int n;
char ch[10];
inline
int read()
ch=getchar();
}while((ch>='0')&&(ch<='9'))
return x*f;
}int main()
int ax=read(),ay=read(),bx=read(),by=read();
if(ay>by)//保證a一定在b右側
if(ch[0]=='o')
else
if(ax==1)
else
}else
if(ch[0]=='c')
else
if(ax==1)
else
}else
else
if((ax==1)&&(bx==2))
else
if((ax==2)&&(bx==1))
else
if(ans)
else}}
return
0;}
SHOI2008 堵塞的交通
有一篇超級棒的線段樹 大力分類討論的題解!戳我 可是我還是不會寫這個做法qwqwqwq 這裡提供線段樹分治的寫法。感覺比較不需要智商,就是跑的有點慢了。include include include include include include include include define max...
SHOI2008 堵塞的交通
這裡提供幾種不用腦子的演算法 當然是離線的 text 記下每條邊的刪除時間,用 text 維護最大生成樹,每次加進一條邊時,跟原來那條鏈上的做比較,刪除那條刪除時間最短的邊即可。線段樹分治 這個演算法將每條邊的加入和刪除時間加入到線段樹中,所以在遍歷到葉子節點時,那個時刻存在的邊都已經在並查集上了,...
SHOI2008 堵塞的交通
有一天,由於某種穿越現象作用,你來到了傳說中的小人國。小人國的布局非常奇特,整個國家的交通系統可 以被看成是乙個2行c列的矩形網格,網格上的每個點代表乙個城市,相鄰的城市之間有一條道路,所以總共有2c個 城市和3c 2條道路。小人國的交通狀況非常槽糕。有的時候由於交通堵塞,兩座城市之間的道路會變得不...