hdu 1588 Gauss Fibonacci

这个挺不错的,要考虑的问题很多,首先是矩阵2分快速幂,再就是矩阵的求和。

在矩阵的求和中要用到快速2分,采用递归来求……

#include<iostream>
#include<stdio.h>
using namespace std;
typedef
__int64 int64;
long
k,b,n,mod;
struct
matrix
{

    int64 a[2][2];
    void
init()
    {

        a[0][0]=a[0][1]=a[1][0]=1;
        a[1][1]=0;
    }

    void
e()
    {

        a[0][0]=a[1][1]=1;
        a[0][1]=a[1][0]=0;
    }
};

matrix e;
matrix mul(matrix m,matrix n)
{

    matrix ans;
    for
(int i=0;i<2;i++)
        for
(int j=0;j<2;j++)
        {

            ans.a[i][j]=0;
            for
(int k=0;k<2;k++)
                ans.a[i][j]+=m.a[i][k]*n.a[k][j];
            ans.a[i][j]%=mod;
        }

    return
ans;
}

matrix add(matrix m,matrix n)
{

    matrix ans;
    for
(int i=0;i<2;i++)
        for
(int j=0;j<2;j++)
        {

            ans.a[i][j]=m.a[i][j]+n.a[i][j];
            ans.a[i][j]%=mod;
        }

    return
ans;
}

matrix fun1(matrix m,long n)
{

    matrix ans;
    ans.e();
    while
(n)
    {

        if
(n&1)
            ans=mul(m,ans);
        n>>=1;
        m=mul(m,m);
    }

    return
ans;
}

matrix fun2(matrix m,long n)
{

    if
(n==1)
        return
m;
    else if
(n&1) return add(fun1(m,n),fun2(m,n-1));
    else return
mul(fun2(m,n>>1),add(fun1(m,n>>1),e));
}

int
main()
{

    while
(scanf("%d%d%d%d",&k,&b,&n,&mod)!=EOF)
    {

        e.e();
        matrix p,ans,a1;
        p.init();a1.init();
        p=fun1(p,k);
        ans=e;
        ans=add(ans,fun2(p,n-1));
        if
(b!=0)
        {

            a1=fun1(a1,b);
            ans=mul(a1,ans);
        }

        printf("%I64d\n",ans.a[0][1]%mod);
    }

    return
0;
}

你可能感兴趣的:(fibonacci)