题目
题目链接:深度自同构
思路
深度同构的森林是由同种类的树构成的,所以我们把树有多少种求出来结果就出来了。先考虑 n 个点的合法的树的个数,容易发现根据要求每个节点的所有 子树的形态必定完全相同。每个合法树根节点下面接的节点为X个节点数为Y的合法树构成,所以我们可以从前往后遍历得出所有树的种类。因此可以递推,令 fi 表示 i 个点的合法的树的 个数,枚举根的儿子个数,有 fi = ∑ d|(i−1) fd。
树
for (int i = 1; i < n; i++)//树
{
for (int j = 1; i * j < n; j++)
{
(f[i * j + 1] += f[i]) %= mod;
}
}
每个合法森林由X个节点数为Y的合法树构成,同上。
森林
for (int i = 1; i <= n; i++)//森林
{
for (int j = 1; i * j <= n; j++)
{
(ans[i * j] += f[i]) %= mod;
}
}
最终代码
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define mod 998244353
int f[1000005] = { 0 }, ans[1000005] = { 0 };
int main()
{
int n;
cin >> n;
f[1] = 1;
for (int i = 1; i < n; i++)//树
{
for (int j = 1; i * j < n; j++)
{
(f[i * j + 1] += f[i]) %= mod;
}
}
for (int i = 1; i <= n; i++)//森林
{
for (int j = 1; i * j <= n; j++)
{
(ans[i * j] += f[i]) %= mod;
}
}
for (int i = 1; i <= n; i++)
{
printf("%d ", ans[i]);
}
return 0;
}