题目描述
如果一个数 x的约数和 y(不包括他本身)比他本身小,那么 x 可以变成 y,y 也可以变成 x。例如 4 可以变为 3,1 可以变为 7。限定所有数字变换在不超过 n 的正整数范围内进行,求不断进行数字变换且不出现重复数字的最多变换步数。
输入格式
输入一个正整数 n。
输出格式
输出不断进行数字变换且不出现重复数字的最多变换步数。
样例
样例输入
7
样例输出
3
样例说明
一种方案为 4→3→1→7。
数据范围与提示
对于 100%的数据,1≤n≤50000。
首先预处理出小于N的每个数的约数和sum[i]。
对于每个数i,如果sum[i]<i,那么i和sum[i]可以互相转化,即两点间连一条边,i为sum[i]的一个儿子。
显然最后的结果是一棵树,问题就转化为了求这棵树的直径。
一棵树的直径被根节点分为两段,分别是根结点到距离根最远的两个叶子。
用dis[i]表示以i为根的子树到叶子结点的最长路径,dis2表示次长路径。
对于每个点i,更新其子结点的dis和dis2即可。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 100010
using namespace std