hdu 2065

hdu 2065 "红色病毒"问题 指数型母函数

1.

由题知:

(1+x/1!+x^2/2!+``+x^n/n!)^2*(1+x^2/2!+```)^2

由e^x=1+x/1!+x^2/2!+```知

原式=e^(2*x)*((e^x+e^(-x))/2)^2

  =(1/4)*(e^(2*x)+1)^2

  =(1/4)*(e^(4*x)+2*e^(2*x)+1)

  =(1/4)*(sia(4^n)*(x^n/n!)+2*sia(2^n)*(x^n/n!)+1)

  由以上式子可知:

  x^n/n!的系数为(4^n+2*2^n+1)/4=4^(n-1)+2^(n-1)+1/4

对于本题只需要计算(4^(n-1)+2^(n-1))%100即可。

其中设计大数取余

2.

 

    一开始以为递推公式是f[n]=2*f[n-1]+2*f[n-2]。但这个公式显然是错的,这个公式相当于限制了A,C必须成对出现,比如ABA这种就计算不到了。

    到网上搜了一下才发现原来公式是这样的,设f1[n]为长度为n的序列,A,C都出现偶数次的方法数;f2[n]为长度为n的序列,A出现奇数次,C出现偶数次的方法数;f3[n]为长度为n的序列,A出现偶数次,C出现奇数次的方法数;f4[n]为长度为n的序列,A,C都出现奇数次的方法数。
    f1[n] = 2*f1[n-1] + f2[n-1] + f3[n-1];
    f2[n] = f1[n-1] + 2*f2[n-1] + f4[n-1];
    f3[n] = f1[n-1] + 2*f3[n-1] + f4[n-1];
    f4[n] = f2[n-1] + f3[n-1] + 2*f4[n-1];
使用矩阵递推即可。

# include <stdio.h>

# define MATRIX_ORDER 4

# define MOD 100

//一维乘二维矩阵

void mul12n(int a[MATRIX_ORDER], int b[MATRIX_ORDER][MATRIX_ORDER], int c[MATRIX_ORDER])

{

    int i, j, rst[MATRIX_ORDER] ;

    for (i = 0 ; i < MATRIX_ORDER ; i++)

    {

        rst[i] = 0 ;

        for (j = 0 ; j < MATRIX_ORDER ; j++)

            rst[i] = (rst[i] + a[j]*b[j][i]) % MOD ;

    }

    for (i = 0 ; i < MATRIX_ORDER ; i++)

        c[i] = rst[i] ;

}

//二维乘二维矩阵

void muln2n(int a[MATRIX_ORDER][MATRIX_ORDER], int b[MATRIX_ORDER][MATRIX_ORDER], int c[MATRIX_ORDER][MATRIX_ORDER])

{

    int i, j ;

    int rst[MATRIX_ORDER][MATRIX_ORDER] ;

    for (i = 0 ; i < MATRIX_ORDER ; i++)

        mul12n (a[i], b, rst[i]) ;

    for (i = 0 ; i < MATRIX_ORDER ; i++)

        for (j = 0 ; j < MATRIX_ORDER ; j++)

            c[i][j] = rst[i][j] ;

}

//矩阵快速幂

void matrix_qpow(int a[MATRIX_ORDER][MATRIX_ORDER], int c[MATRIX_ORDER][MATRIX_ORDER], unsigned long long n)

{

    int i, j ;

    int rst[MATRIX_ORDER][MATRIX_ORDER], buf[MATRIX_ORDER][MATRIX_ORDER] ;

    for (i = 0 ; i < MATRIX_ORDER ; i++)

        for (j = 0 ; j < MATRIX_ORDER ;j++)

        {

            rst[i][j] = 0 ;

            if (i == j) rst[i][j] = 1 ;

            buf[i][j] = a[i][j] ;

        }

    while (n)

    {

        if (n&1) muln2n(rst, buf, rst) ;

        muln2n (buf, buf, buf) ;

        n >>= 1 ;

    }

    for (i = 0 ; i < MATRIX_ORDER ; i++)

        for (j = 0 ; j < MATRIX_ORDER ; j++)

            c[i][j] = rst[i][j] ;

}

int main ()

{

    int c[4], a[4] = {1, 0, 0, 0} ;

    int b[4][4] = {2, 1, 1, 0, 1, 2, 0, 1, 1, 0, 2, 1, 0, 1, 1, 2} ;

    int rear[4][4] ;

    int T, Case ;

    long long n ;

    while (~scanf ("%d", &T) && T)

    {

        Case = 1 ;

        while (T--)

        {

            scanf ("%I64u", &n) ;

            matrix_qpow(b, rear, n) ;

            mul12n(a, rear, c) ;

            printf ("Case %d: %d\n", Case++, c[0]) ;

        }

        printf ("\n") ;

    }

    return 0 ;

}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值