1. 程式人生 > >【模板】樹的直徑 DP (模板題:XJOI數字轉換)

【模板】樹的直徑 DP (模板題:XJOI數字轉換)

題目描述:

如果一個數x的約數和(不包括它本身,下同)比它本身小,那麼x可以變成它的約數和;如果對於某個y>x且y的約數和為x,那麼x也可以變成y。例如,4可以變為3,1可以變為7。限定所有的數字變換在不超過n的正整數範圍內進行,求不斷進行數字變換且沒有重複數字出現的最多變換步數。

輸入格式:

輸入一個正整數n。

輸出格式:

輸出最多的步數。

樣例輸入:

7

樣例輸出:

3

資料範圍:

1<=n<=50000

#include<iostream>
using namespace std;
int s[50010],m1[50010],m2[50010];
	//s是約數和,m1是以該節點為根的子樹中的最長鏈,
	//			 m2是以該節點為根的子樹中的次長鏈; 
int main(){
	int n,ans=0;cin >>n;
	for (int i=1;i<=n/2;++i)
	for (int j=i*2;j<=n;j+=i)
		s[j]+=i;
	
	for (int i=n;i;--i){
		if (s[i]>=i) continue;
		if (m1[i]+1>m1[s[i]])
			m2[s[i]]=m1[s[i]],m1[s[i]]=m1[i]+1;
		else if (m1[i]+1>m2[s[i]])
			m2[s[i]]=m1[i]+1;
	}
	
	for (int i=1;i<=n;++i)
		ans=max(ans,m1[i]+m2[i]);
	
	cout <<ans<<endl;
	return 0;
}