码迷,mamicode.com
首页 > 其他好文 > 详细

Yue Fei's Battle(组合计数递推)

时间:2017-07-22 09:41:36      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:long   16px   mod   iostream   init   src   print   pac   str   

技术分享

 

 

//求一个直径为 k 的树有多少种形态,每个点的度不超过 3 

技术分享

 

 

// 非常完美的分析,学到了,就是要细细推,并且写的时候要细心

还有除法取模需要用逆元

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define MOD 1000000007
#define LL long long
#define MX 100005

LL dp[MX];
LL sum[MX];
LL inv2;
LL inv6;

LL quick(LL a,LL b)
{
    LL ret = 1;
    while (b)
    {
        if (b&1) ret = ret*a%MOD;
        a = a*a%MOD;
        b/=2;
    }
    return ret;
}

void Init()
{
    inv2 = quick(2,MOD-2);
    inv6 = quick(6,MOD-2);
    dp[0]=1,sum[0]=1;
    dp[1]=1,sum[1]=2;
    for (int i=2;i<MX;i++)
    {
        dp[i] = dp[i-1]*(dp[i-1]-1)%MOD*inv2%MOD;
        dp[i] = (dp[i] + dp[i-1])%MOD;
        dp[i] = (dp[i] + dp[i-1]*sum[i-2]%MOD)%MOD;
        sum[i]=(sum[i-1]+dp[i])%MOD;
    }
}

int main()
{
    int n;
    Init();

    while (scanf("%d",&n)&&n)
    {
        if (n%2==0)
        {
            int i = n/2;
            int ans = (dp[i]+dp[i]*(dp[i]-1)/2)%MOD;
            printf("%d\n",ans);
        }
        else
        {
            int i = n/2;

            int ans = (((dp[i]*(dp[i]+1))%MOD*inv2%MOD)*sum[i-1])%MOD;

            ans = (ans + dp[i])%MOD;
            ans = (ans + (dp[i]*(dp[i]-1)%MOD)%MOD)%MOD;
            ans = (ans + dp[i]*(dp[i]-1)%MOD*(dp[i]-2)%MOD*inv6%MOD )%MOD;
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

Yue Fei's Battle(组合计数递推)

标签:long   16px   mod   iostream   init   src   print   pac   str   

原文地址:http://www.cnblogs.com/haoabcd2010/p/7220256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!