数字转换

https://loj.ac/problem/10155

因为一个i对应一个约数和,所以i向i的约数和连线会构成一棵树,i是i的约数和(a[i])的儿子

计算树的直径、最长链

设d1[i]表示i到 以i为根的子树中 的 叶子结点的最长距离,d2[i]表示次长,u[i]表示直径

d1[i]=max(d1[i的儿子]+1)

u[i]=d1[i]+d2[i]

#include<bits/stdc++.h>
using namespace std;
int a[100000],d1[100000],d2[100000];
int main()
{
	int n;
	cin>>n;
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=sqrt(i);j++)
		{
			if(i%j==0)
			{
				a[i]+=j;
				if(i/j!=j&&j!=1) a[i]+=i/j;//注意一下QAQ
			} 
		}
	}
	for(int i=n;i>=1;i--)//由于题目要求约数和<i,所以编号大的点是儿子
	{
		if(a[i]<i)//i是儿子 
		{
			if(d1[i]+1>d1[a[i]])
			{
				d2[a[i]]=d1[a[i]];
				d1[a[i]]=d1[i]+1;
			}
			else if(d1[i]+1>d2[a[i]])
			{
				d2[a[i]]=d1[i]+1;
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++) ans=max(ans,d1[i]+d2[i]);
	cout<<ans;
	return 0;
}
posted @ 2020-08-26 21:28  zlq,  阅读(137)  评论(0编辑  收藏  举报