First of all, for each number less than n, we can make sure that the sum of its divisors (not including itself) is fixed, just like the sum of the divisors of 4 must be 3, it cannot be other, then we can Calculate sum[i] from the sum of the divisors of each number of 2-n. For sum[i]<i, we connect an edge of sum[i]---->i (because for each i, sum[i] is uniquely determined), which means that each son has a unique parent node, then we will eventually form a forest (multi-class tree), and the longest transformation step in the question will be converted into a tree Longest diameter
Why not start from 1, because the sum of the divisors of 1 is 0 except for itself, and the minimum requirement in the question is 1, so 1 does not meet the requirements
How to find the longest diameter of a tree, we can enumerate each point in turn, find the longest and second longest distances of this point, and then add them together. You can see the longest path of the tree for details. I won’t explain it in detail here.
Code
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>usingnamespace std;constint N =5e4+10;int n;int h[N], e[N], ne[N], idx;int sum[N];//约数之和bool is[N];//是否已经用过int ans;voidadd(int a,int b){
e[idx]= b;
ne[idx]= h[a];
h[a]= idx++;}intdfs(int u){
int d1 =0, d2 =0;for(int i = h[u]; i !=-1; i = ne[i]){
int j = e[i];int d =dfs(j)+1;if(d > d1) d2 = d1, d1 = d;elseif(d > d2) d2 = d;}
ans =max(ans, d1 + d2);return d1;}intmain(){
memset(h,-1,sizeof h);
cin >> n;for(int i =1; i <= n; i++){
for(int j =2; j <= n / i; j++){
//不能是自己的本身
sum[i * j]+= i;}}for(int i =2; i <= n; i++){
if(sum[i]< i){
add(sum[i], i);}
is[i]=true;}for(int i =1; i <= n; i++){
if(!is[i]){
//说明是父节点dfs(i);}}
cout << ans << endl;return0;}