為了讓同學們更好地監督自己,學校推行了刷卡機制。
學校中有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的整數表示,每個地點設有若干個刷卡機。有...