hdu-5015 233 Matrix 矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5015

这题一开始就想到用矩阵快速幂做,不过思路跑歪了,想着从a[n,m]去逆推出a[0,0~m]每一位的倍数关系啥的。发现比较难求解而且233正向递推好写,反向涉及除法就很难写了。

其实没有那么复杂,我们把a[1~n,0]以及下一列的第一位,以及3这个数构造成矩阵,那么对于a[i][j]就可以用之前的矩阵通过矩阵乘法求出了。

#include <iostream>
#include <cstring>
#define LL long long
using namespace std;
const LL mod=10000007;
int mx[105][105];
struct mmx
{
    LL n,m;
    LL c[12][12];//需要根据题目开大
    void initMath(LL _n)//初始化方阵
    {
        m=n=_n;
    }
    void initOne(LL _n)//初始化单位矩阵
    {
        m=n=_n;
        for(LL i=0; i<n; i++)
            for(LL j=0; j<m; j++)
                c[i][j]=(i==j);
    }
    void print()//测试打印
    {
        for(LL i=0; i<n; i++)
        {
            for(LL j=0; j<m; j++)
                cout<<c[i][j]<<' ';
            cout<<endl;
        }
    }
};
mmx Mut(mmx a,mmx b)
{
    mmx c;
    c.n=a.n,c.m=b.m;
    for(LL i=0;i<a.n;i++)
        for(LL j=0;j<b.m;j++)
        {
            LL sum=0;
            for(LL k=0;k<b.n;k++)
                sum+=a.c[i][k]*b.c[k][j],sum%=mod;
            c.c[i][j]=sum;
        }
    return c;
}
mmx fastMi(mmx a,LL b)
{
    mmx mut;mut.initOne(a.n);
    while(b)
    {
        if(b%2!=0)
            mut=Mut(mut,a);
        a=Mut(a,a);
        b/=2;
    }
    return mut;
}
int main()
{
    cin.sync_with_stdio(false);
    LL n,m;
    while(cin>>n>>m)
    {
        n+=2;
        mmx src;
        src.n=1,src.m=n;
        for(int i=1; i<n-1; i++)
            cin>>src.c[0][i];
        src.c[0][0]=233;
        src.c[0][n-1]=3;
        mmx cal;
        cal.initOne(n);
        for(int i=0; i<n+2; i++)
        {
            if(i==0)cal.c[i][0]=10,cal.c[i][n-1]=0;
            else if(i==n-1)cal.c[i][0]=1,cal.c[i][n-1]=1;
            else cal.c[i][0]=0,cal.c[i][n-1]=0;
            for(int j=1;j<n-1;j++)
            {
                if(i==0)cal.c[i][j]=1;
                else if(i==n-1) cal.c[i][j]=0;
                else
                {
                    if(i<=j)cal.c[i][j]=1;
                    else cal.c[i][j]=0;
                }
            }
        }
        //cal.print();
        mmx ans=Mut(src,fastMi(cal,m));

        cout<<ans.c[0][n-2]<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/LukeStepByStep/p/8568527.html