SHOI2008 堵塞的交通traffic

2021-08-13 02:33:08 字數 3843 閱讀 6341

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條道路。小人國的交通狀況非常槽糕。有的時候由於交通堵塞,兩座城市之間的道路會變得不...