# BZOJ 3057圣主的考验题解

T飞~

# include<cstdio>
# include<cstring>
# include<cstdlib>
# include<algorithm>
using namespace std;
typedef long long LL;
const int mn = 3000;
const int mod = 1000000000;
int maxh[31],minh[31],L[mn + 10],R[mn + 10];
LL dp[mn + 10][31],ans[mn + 10];

int main ()
{
dp[0][0]=dp[1][1]=1, ans[1]=1;
minh[1]=1,minh[2]=2;
for(int i=3;i<=30;i++)
minh[i]=minh[i-1]+minh[i-2]+1;
for(int i=1;minh[i]<=mn && i<= 30;i++)
for(int j=minh[i];j<min(minh[i+1],mn+1);j++)
R[j]=i;
maxh[1]=1;
for(int i=2;i<=30;i++)
maxh[i]=maxh[i-1]*2+1;
L[1]=1;
for(int i=2;maxh[i-1]<=mn && i<=30;i++)
for(int j=maxh[i-1]+1;j<=min(maxh[i],mn);j++)
L[j]=i;
for(int i=2;i<=mn;i++)
{
for(int l=0;l<i;l++)
{
int r=i-1-l;
for (int h=max(0,L[i]-2);h<=min(29,R[i]-1);h++)
{
if(h)
dp[i][h+1]+=dp[l][h]*dp[r][h-1];
(dp[i][h+1]+=dp[l][h]*dp[r][h])%=mod;
dp[i][h+2]+=dp[l][h]*dp[r][h+1];
}
}
for(int h=1;h<=min(29,i);h++)
ans[i]+=dp[i][h];
ans[i] %= mod;
}
int n;
while(scanf("%d",&n),n)
printf(n>=38 ? "%09lld\n" : "%lld\n",ans[n]);
return 0;
}

posted @ 2018-09-18 21:41 logeadd 阅读(...) 评论(...) 编辑 收藏