BZOJ 2959 長跑 LCT 並查集

2022-03-29 05:37:18 字數 2294 閱讀 5159

為了讓同學們更好地監督自己,學校推行了刷卡機制。

學校中有n個地點,用1到n的整數表示,每個地點設有若干個刷卡機。

有以下三類事件:

1、修建了一條連線a地點和b地點的跑道。

2、a點的刷卡機台數變為了b。

3、進行了一次長跑。問乙個同學從a出發,最後到達b最多可以刷卡多少次。具體的要求如下:

當同學到達乙個地點時,他可以在這裡的每一台刷卡機上都刷卡。但每台刷卡機只能刷卡一次,即使多次到達同一地點也不能多次刷卡。

為了安全起見,每條跑道都需要設定乙個方向,這條跑道只能按照這個方向單向通行。最多的刷卡次數即為在任意設定跑道方向,按照任意路徑從a地點到b地點能刷卡的最多次數。

容易發現,如果圖中有乙個e-dcc,那麼這上面的所有機器都可以被經過,貢獻為所有點刷卡機台數的最大值。因此我們考慮動態維護e-dcc.

對於每個e-dcc,我們任意選乙個其中的點做代表元,縮成的點的編號就是代表元的編號,權值為所有點權值的最大值。那麼怎麼動態修改這棵樹呢?

首先,可以用並查集維護兩個資訊:

連通性該點所在的e-dcc代表元,記為bel[x]

第1個並查集判斷是否無解用。

第2個並查集需要和lct的輔助樹splay結合在一起。加入一條邊(x,y)時,如果(bel[x],bel[y])在原樹上連通,就會產生乙個e-dcc.縮點的時候我們先split出鏈(bel[x],bel[y])。然後暴力dfs這條鏈,把鏈上節點的bel改成bel[y].接著斷開鏈上除了y的其他節點,直接lson(y)=0即可。根據均攤分析,複雜度不會超限。

在splay維護(如rotate等)時,我們把原來的splay模板裡的fa(x)改成x所在v-dcc的代表元的父親。比如我們的rotate可以改寫成這樣。

int find_bel(int x) 

void rotate(int x)

細節比較多,詳情見**。

#include#include#include#include#define maxn 750000

using namespace std;

int n,m;

inline void qread(int &x)

while(c>='0'&&c<='9')

x=x*sign;

}inline void qprint(int x)else if(x==0)else

}struct lcttree[maxn+5];

int bel[maxn+5];

//並查集維護雙連通分量關係,這裡不能直接用splay的fa(雖然也要儲存);

//選聯通分量中的乙個節點作為代表節點

//lct模板裡的fa(x)用find_bel(fa(x))代替,相當於每次跳到fa(x)所在e-dcc的代表節點

//如果兩個點的fa不相等,則說明不在乙個e-dcc中

int find_bel(int x)

int con_id[maxn+5]; //並查集維護連通性

int find_con(int x)

void merge_con(int x,int y)

void push_up(int x)

inline bool is_root(int x)

int check(int x)

void reverse(int x)

void push_down(int x)

} void push_down_all(int x)

void rotate(int x)

void splay(int x)

rotate(x);

} push_up(x);

} void access(int x)

} void make_root(int x)

void split(int x,int y)

void link(int x,int y)

void cut(int x,int y)

void update_val(int x,int val)

void dfs_tree(int x,int y)

void shrink(int x,int y)

int query_sum(int x,int y)

}t;//int bel[maxn+5];

int a[maxn+5];

int main()

// for(int i=1;i<=n;i++) bel[i]=i;

for(int i=1;i<=m;i++)else

}}else if(type==2)else

}}

bzoj 2959 長跑(LCT 並查集)

time limit 10 sec memory limit 256 mb submit 315 solved 178 submit status discuss 某校開展了同學們喜聞樂見的陽光長跑活動。為了能 為祖國健康工作五十年 同學們紛紛離開寢室,離開教室,離開實驗室,到操場參加3000公尺長...

BZOJ2959 長跑(lct 並查集)

傳送門 用lct維護一顆動態樹。如果連了某一條邊形成了乙個環,證明一次長跑這個環上的所有的點都可以被統計,所以可以將這個環縮成乙個點。用ufs來實現。那麼一次長跑實際上就是在一條樹鏈上跑,只有乙個方向,在lct上維護乙個sum就可以了。時間複雜度是均攤的,因為每乙個點至多被縮點一次,所以o k ml...

bzoj2959 長跑 LCT 並查集

某校開展了同學們喜聞樂見的陽光長跑活動。為了能 為祖國健康工作五十年 同學們紛紛離開寢室,離開教室,離開實驗室,到操場參加3000公尺長跑運動。一時間操場上熙熙攘攘,摩肩接踵,盛況空前。為了讓同學們更好地監督自己,學校推行了刷卡機制。學校中有n個地點,用1到n的整數表示,每個地點設有若干個刷卡機。有...