BZOJ4537 HNOI2016 最小公倍數

2021-08-13 09:28:11 字數 1031 閱讀 9343

那個,事情是這樣的,從前有乙隻蒟蒻(對,就是我),然後有一天他心血來潮想創個部落格。。

可是沒過多久,他的熱情就過去了,甚至連一篇博文都沒有寫。。

然後,不知道怎麼了,他的部落格就被機房裡的dalao翻出來了,還被嘲諷了一番。。

於是他決定補救一下他的部落格。。嗯,就這樣。。

這道題大概是這樣的。。給定一張n個點m條邊的帶權無向圖,圖上的邊權都是

然後給定q個詢問,詢問有四個引數u,v,a,b,問是否存在一條從u到v的路徑使得路徑上所有邊權的最小公倍數為

首先,轉化一下題目。。最小公倍數的部分相當於路徑上最大的a值和b值等於詢問的a值和b值

然後又不一定需要是簡單路徑,所以所求路徑等價於包含u和v的乙個連通塊

對於前20%的資料,暴力演算法十分的明顯,對於每個詢問i,維護乙個並查集,只加入

最後只要滿足f[u]==f[v]且並查集內最大的a值和b值等於ai和bi則符合題意,然而這個演算法只能獲得20%的分數

考慮用分塊優化這個暴力,將所有的邊按a排序

對於第i個塊,將a值在塊的值的範圍內的詢問取出來

將前i-1個塊的邊和取出來的詢問按b排序,由於所有的a滿足要求,b的值為遞增的,將邊按順序加入並查集,判斷一下即可。

考慮對答案有貢獻的邊有可能在第i個塊內,且詢問的a並不是遞增的,所以需要對於每個詢問,將第i個塊內的邊依次加入,判斷後刪除即可,這樣的邊最多

時間複雜度為

#include#include#includeusing std::sort;

const int n=50005;

inline int read()

while(47>31));}

inline void swap(int &a,int &b)

inline int get(int x)

inline void merge(int u,int v,int a,int b)

{ u=get(u);v=get(v);

if(s[v]=e[i].a&&(x>m||q[j].a

bzoj4537 HNOI2016 最小公倍數

time limit 40 sec memory limit 512 mb submit 563 solved 236 submit status discuss 給定一張n個頂點m條邊的無向圖 頂點編號為1,2,n 每條邊上帶有權值。所有權值都可以分解成2 a 3 b 的形式。現在有q個詢問,每次...

BZOJ4537 Hnoi2016 最小公倍數

給定一張n個頂點m條邊的無向圖 頂點編號為1,2,n 每條邊上帶有權值。所有權值都可以分解成2 a 3 b 的形式。現在有q個詢問,每次詢問給定四個引數u v a和b,請你求出是否存在一條頂點u到v之間的路徑,使得 路徑依次經過的邊上的權值的最小公倍數為2 a 3 b。注意 路徑可以不是簡單路徑。下...

bzoj4537 Hnoi2016 最小公倍數

傳送門 思路 把邊按a排序,每sqrt m 分一組 然後把詢問按b排序,把在這組及以前的邊按b排序 把這些邊用並查集一條一條插入並維護 零散的部分暴力插入並記錄,做完後暴力撤銷 注意 並查集不能路徑壓縮,否則無法撤銷回去 include include include include include...