题意:求深度为n的无根树有多少种构型。
思路:分为两种情况,n为奇数或者偶数
首先令
dp[i]
为深度为k的子树的个数
dp[i]=∑k−2j=0dp[i]+(dp[k−1]∗dp[k−1]+dp[k−1])/2
ps:
(dp[k−1]∗dp[k−1]+dp[k−1])/2=c[dp[k−1]+2−1,2]
(插棍法)
1.
n
为偶数,分为n2的两个子串,令每个子串的种数为
dp[n2]
,则总数为
ans=(dp[n2]2+dp[n2])/2
ps:后半部分原理同上(插棍法)
2.
n
为奇数,分为n−12的两个子串,因为中间还有一个节点,所以还可以另外起一条边,所以结果就是
ans=(dp[n−12]2+dp[n−12])/2∗∑j=0n−12−1dp[j]+dp[n−12]3+3∗dp[n−12]2+2∗dp[n−12]
代码
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define maxn 111111
long long dp[maxn], sum[maxn];
long long k;
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
if(a==0&&b==0) return -1;
if(b==0){x=1;y=0;return a;}
long long d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
long long mod_rev(long long a,long long n)
{
long long x,y;
long long d=extend_gcd(a,n,x,y);
if(d==1) return (x%n+n)%n;
else return -1;
}
int main () {
dp[0] = 1, dp[1] = 1;
sum[0] = 1,sum[1] = 2;
for (long long i = 2; i < maxn; i++) {
dp[i] = dp[i-1]*sum[i-2]; dp[i] %= mod;
dp[i]+=(dp[i-1]*dp[i-1]%mod+dp[i-1])%mod*mod_rev (2, mod)%mod;
sum[i] = sum[i-1] + dp[i]; sum[i] %= mod;
}
while (cin>>k && k) {
if(k&1) {
long long tt=(k-1)/2;
long long ans1=0;
ans1=(dp[tt]*dp[tt]%mod+dp[tt])%mod*mod_rev (2, mod)%mod;
long long ans2=0;
for(int i=0;i<=tt-1;i++) {
ans2+=ans1*dp[i];
ans2%=mod;
}
long long xx=dp[tt];
ans2+=(xx*xx%mod*xx%mod+xx*xx%mod*3+2*xx)%mod*mod_rev (6, mod)%mod;
cout << ans2%mod << endl;
}
else {
long long tt=k/2;
long long ans=0;
ans=(dp[tt]*dp[tt]%mod+dp[tt])*mod_rev (2, mod)%mod;
cout << ans%mod << endl;
}
}
return 0;
}