传送门:QAQQAQ

题意:如果一个数x的约数和(不包括它本身,下同)比它本身小,那么x可以变成它的约数和;如果对于某个y>x且y的约数和为x,那么x也可以变成y。例如,4可以变为3,1可以变为7。限定所有的数字变换在不超过n的正整数范围内进行,求不断进行数字变换且没有重复数字出现的最多变换步数。

思路:YY一下,若$x$可以变为$y$,则$y$也一定能变为$x$,所以我们对于可以互相变换的点建一条无向边,因为每一个点最多之和一个值比它小的点连边,所以不可能出现环(这点可以人工YY证明)

所以我们在这个无环“森林”中跑一个最长链即可

代码:(其实以1为根跑直径不够严谨,用DP算最长链更好)

#include<bits/stdc++.h>
using namespace std; vector<int> v[];
int d[]; void dfs(int u,int f,int depth)
{
d[u]=depth;
for(int i=;i<(int)v[u].size();i++)
{
if(v[u][i]==f) continue;
dfs(v[u][i],u,depth+);
}
} void init(int n)
{
for(int i=;i<=n;i++)
{
int sum=;
for(int j=;j*j<=i;j++)
{
if(i%j==)
{
sum+=j;
if(j*j!=i&&j!=) sum+=i/j;
}
}
if(sum<i)
{
v[sum].push_back(i);
v[i].push_back(sum);
}
}
// for(int i=1;i<=n;i++)
// {
// cout<<i<<":";
// for(int j=0;j<v[i].size();j++) cout<<v[i][j]<<" ";
// cout<<endl;
// }
} int main()
{
int n; cin>>n;
init(n);
dfs(,-,);
int s=-,maxn=-;
for(int i=;i<=n;i++)
{
if(maxn<d[i])
{
maxn=d[i];
s=i;
}
}
dfs(s,-,);
for(int i=;i<=n;i++)
{
if(maxn<d[i]) maxn=d[i];
}
cout<<maxn<<endl;
return ;
}

最新文章

  1. C++类型转换函数
  2. postgresql 服务器端编程之hello word
  3. 一次蜿蜒曲折的RFID破解之路
  4. 整合Open vSwitch与DNSmasq为虚拟机提供DHCP功能
  5. Swift标识符和关键字
  6. jQuery如何阻止子元素继承父元素事件?
  7. SKPhysicsBody类
  8. PLSQL Developer安装(Oracle11g+win7_64bit)
  9. “MEAN”技术栈开发web应用
  10. webstrom命令大全
  11. CentOS6+MySQL5.6二进制安装
  12. 如何检测浏览器url变化
  13. Python爬虫入门教程 50-100 Python3爬虫爬取VIP视频-Python爬虫6操作
  14. win10 vscode使用 智能提示
  15. 播放器更改语言归属地后Cnario player软件无法启动的问题
  16. Powershell中显示隐藏文件
  17. HTML5 元素属性介绍
  18. 百度前端技术学院-task1.8源代码以及个人总结
  19. WCF创建简单程序
  20. centos安装docker-ce shell脚本

热门文章

  1. selenium提取不了标签文本
  2. flink on yarn启动失败
  3. Oracle使用——PLSQL的中文乱码显示全是问号--Oracle查询中文乱码
  4. Python自学:第四章 复制列表(1)
  5. thinkphp 查询缓存
  6. Delphi exe实例之间传递cmd参数
  7. MySQL数据库迁移详细步骤
  8. 2019 牛客多校第二场 H Second Large Rectangle
  9. 20140320 roc曲线 sizeof
  10. spark-sql性能优化之——多线程实现多Job并发执行