bzoj 4537 最小公倍數

2022-06-01 05:03:09 字數 1736 閱讀 4445

給定一張n個頂點m條邊的無向圖 每條邊上帶有權值 所有權值都可以分解成2^a*3^b的形式

q個詢問,每次詢問給定四個引數u、v、a和b,請你求出是否存在一條頂點u到v之間的路徑,使得路徑依次經過的邊上的權值的最小公倍數為2^a*3^b

注意:路徑可以不是簡單路徑

下面是一些可能有用的定義:

最小公倍數:k個數a1,a2,…,ak的最小公倍數是能被每個ai整除的最小正整數

路徑:路徑p:p1,p2,…,pk是頂點序列,滿足對於任意1<=ii和pi+1之間都有邊相連

簡單路徑:如果路徑p:p1,p2,…,pk中,對於任意1<=s≠t<=k都有ps≠pt,那麼稱路徑為簡單路徑

思路:對於每個詢問(u,v,a,b),將a<=a和b<=b的邊全部加入並查集中,最後判斷u和v是否在同一連通分量中且連通分量包含的最大的a=a,最大的b=b即可

把詢問和邊離線按a排序,詢問時在已經加入的邊中按b值排序加入並查集中

結合起來,按a值將詢問和邊分塊,前面的邊按第二種做法做,塊內的邊按第一種做法做就行了

因為並查集需要支援撤銷,所以要用按秩合併

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9

#define inf 2139062143

10#define ll long long

11#define maxn 100100

12using

namespace

std;

13 inline int

read()

1417

while(isdigit(ch))

18return x*f;19}

20int

n,m,t,fa[maxn],rnk[maxn],f,pos,b,mxp[maxn],mxq[maxn],top,cnt,size,ans[maxn];

21struct

data

2225 }qs[maxn],e[maxn<<1],tmp[maxn<<2

];26

struct stckst[maxn<<1

];27

int find(int x)

28void merge(int u,int v,int p,int

q)29

;33 fa[y]=x;

34 mxp[x]=max(p,max(mxp[y],mxp[x]));

35 mxq[x]=max(q,max(mxq[x],mxq[y]));

36if(rnk[x]==rnk[y]) rnk[x]++;37}

38bool cmp(data a,data b)

39void

dlt()

4043

intmain()

4481

if(e[k].q<=tmp[j].q) merge(e[k].u,e[k].v,e[k].p,e[k].q);82}

83}84else

merge(tmp[j].u,tmp[j].v,tmp[j].p,tmp[j].q);85}

86}87 tot=0;88

}89}90

for(int i=1;i<=t;i++)

91 puts(ans[i]?"

yes":"no"

);92 }

view code

最小公倍數

最大公倍數最大是兩個數的乘積,兩個數互質 最大公約數是1 幾個數共有的倍數叫做這幾個數的公倍數,其中除0以外最小的乙個公倍數,叫做這幾個數的最小公倍數。記作 a,b 與最小公倍數相對應的概念是最大公約數,a,b的最大公約數記為 a,b 關於最小公倍數與最大公約數,我們有這樣的定理 a,b a,b a...

最小公倍數

問題描述 編寫一函式lcm,求解兩個正整數的最小公倍數。樣例輸入 乙個滿足題目要求的輸入樣例。例 3 5 樣例輸出 與上面樣例對應的輸出。例 15 資料規模和約定 輸入資料中每乙個數的範圍 例 兩個數都小於65536.演算法分析 一般來說,求兩個正整數a b的最小公倍數的演算法思路很簡單,主要分為以...

最小公倍數

求n個數的最小公倍數。輸入 輸入包含多個測試例項,每個測試例項的開始是乙個正整數n 2 n 10 然後是n個正整數。輸出為每組測試資料輸出它們的最小公倍數,每個測試例項的輸出佔一行。你可以假設最後的輸出是乙個32位的整數。樣例輸入 2 4 6 3 2 5 7 樣例輸出 1270 題目 zjgsuto...