题目描述:
如果一个数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;
}