列举免费域名注册的网站,网站建设到上线的步骤过程,网站移动转换,互联网金融公司排名如何对一个问题挖掘信息把它变成已知的问题十分重要#xff0c;这一题恰恰体现这一点#xff1a;
https://www.acwing.com/problem/content/1077/
首先#xff0c;对于一个数x#xff0c;它对应一个其约数之和y#xff0c;同时他们可以相互转换#xff0c;于是我们可以…如何对一个问题挖掘信息把它变成已知的问题十分重要这一题恰恰体现这一点
https://www.acwing.com/problem/content/1077/
首先对于一个数x它对应一个其约数之和y同时他们可以相互转换于是我们可以给他们连一条边。
这样子1--n的数就抽象成图中的点我们进一步看看约数之和自己的条件这就避免了出现回路假如有A,B,C构成一个回路那么令A的约数之和为BB的约数之和为C那么A只能是C的约数之和于是ABCA,矛盾
于是整个图就可以抽象成森林。问题就是求每一个树的最大转换次数也就是求最长链这一经典问题。
考虑n50000直接暴力枚举肯定TLE我们可以参考毕业季那题从因子出发枚举它倍数即可nlogn)
下面是AC代码
#includebits/stdc.h
using namespace std;
int n;
int a[500010];
int vis[500010];
int ans0;
int res0;
vectorint edge[500010];
int dfs(int root,int fa){vis[root]1;int dist 0; // 表示从当前点往下走的最大长度int d1 0, d2 0;for (int i 0; iedge[root].size(); i){int j edge[root][i];if (j fa) continue;int d dfs(j, root) 1;dist max(dist, d);if (d d1) d2 d1, d1 d;else if (d d2) d2 d;}ans max(ans, d1 d2);return dist;
}
int main(){cinn;for(int i1;in;i){for(int k2;k*in;k){a[k*i]i;}}for(int i2;in;i){if(a[i]i) continue;edge[i].push_back(a[i]);edge[a[i]].push_back(i);}for(int i2;in;i){if(vis[i]) continue;ans0;dfs(i,-1);resmax(res,ans);}coutres;
}