ACWing 1075 數字轉換

2021-10-22 01:55:14 字數 1897 閱讀 3956

如果乙個數x

xx的約數之和y

yy(不包括他本身)比他本身小,那麼x

xx可以變成y

yy,y

yy也可以變成x

xx。例如,4

44可以變為3

33,1

11可以變為7

77。限定所有數字變換在不超過n

nn的正整數範圍內進行,求不斷進行數字變換且不出現重複數字的最多變換步數。

輸入格式:

輸入乙個正整數nnn。

輸出格式:

輸出不斷進行數字變換且不出現重複數字的最多變換步數。

資料範圍:

1 ≤n

≤50000

1≤n≤50000

1≤n≤50

000

設s (x

)=∑d

∣x,1

≤d≤x

ds(x)=\sum_ d

s(x)=∑

d∣x,

1≤d≤

x​d,也就是說當y=s

(x

)<

xy=s(x)y=

s(x)

<

x,那麼x

xx和y

yy可以相互轉化。我們考慮一下互相轉化的數所構成的圖有什麼性質。如果y

y<

x,那麼有可能有另乙個數z

zz,也滿足y=s

(z

)y=s(z)

y=s(z)

,這樣y

yy和z

zz也能相互轉化,但是比x

xx小的且能與x

xx互相轉化的數是唯一的,就是s(x

)s(x)

s(x)

。所以我們可以構造乙個從s(x

)→

xs(x)\to x

s(x)→x

的有向邊,這樣所有轉化關係形成的圖就是個森林,每棵樹是個有根樹。問題就轉化為了求樹中的最長路徑的長度是多少,參考**如下:

#include

#include

using

namespace std;

const

int n =

50010

, m =

2* n;

int n;

int h[n]

, e[m]

, ne[m]

, idx;

int sum[n]

;// 存每個節點是否是樹根,避免重複列舉森林中的樹

bool is_root[n]

;int res;

void

add(

int a,

int b)

intdfs

(int u)

res =

max(res, d1 + d2)

;return d1;

}int

main()

for(

int i =

1; i <= n; i++)if

(is_root[i]

)dfs

(i);

cout << res << endl;

return0;

}

時間複雜度o(n

log⁡n)

o(n\log n)

o(nlogn)

(主要的時間花在了兩重迴圈上,n(∑

k=2n

1k)=

o(

nlog⁡n

)n(\sum_^\frac)=o(n\log n)

n(∑k=2

n​k1

​)=o

(nlogn

)),空間o(n

)o(n)

o(n)

AcWing 1075 數字轉換

題目描述 如果乙個數 x 的約數之和 y 不包括他本身 比他本身小,那麼 x 可以變成 y,y 也可以變成 x。例如,4 可以變為 3,1可以變為 7。限定所有數字變換在不超過 n 的正整數範圍內進行,求不斷進行數字變換且不出現重複數字的最多變換步數。輸入格式 輸入乙個正整數 n。輸出格式 輸出不斷...

acwing 1075 數字轉換 (樹形DP)

首先,對於小於n的每個數,我們可以確定它的約數之和 不包括自己 是固定的,就像4的約數之和一定是3,不可能是其他的,那麼我們就可以將2 n的每個數的約數之和求出sum i 對於sum i i 的邊 因為對於每個i,sum i 是唯一確定的 也就是說每個兒子都有唯一乙個父節點,那麼我們最終就會構成森林...

AcWing1075 數字轉換 樹形DP 題解

題目傳送門 如果乙個數 x 的約數之和 y 不包括他本身 比他本身小,那麼 x 可以變成 y,y 也可以變成 x。例如,4 可以變為 3,1 可以變為 7。限定所有數字變換在不超過 n 的正整數範圍內進行,求不斷進行數字變換且不出現重複數字的最多變換步數。輸入格式 輸入乙個正整數 n。輸出格式 輸出...