BZOJ 2326 [HNOI2011]数学作业

本文介绍了一种利用分段递推结合矩阵快速幂的方法来解决特定数学问题的技术。通过构造特定矩阵并利用矩阵乘法的性质,可以在较短时间内求得复杂递推式的解。适用于处理大规模数据集的大整数计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分段递推+矩阵乘法

根据模运算的分配律,i表示连接到第几个数,有递推式:f[i]= f[i-1]*(10^log(i))+i mod M

构造矩阵进行加速

{f[i-1],i-1,1}
*
{ 10^log(i) ,, 0 ,, 0 }
{ 1 ,,,,,,,,,,,,,,,,,, 1 ,, 0 }
{ 0 ,,,,,,,,,,,,,,,,,, 1 ,, 1 }

(空格没法对齐,强行用逗号对齐)

#include<cstdio>
#include<cstring>
#define ll long long
ll m;
struct matrix
{
    ll mat[4][4];

    matrix()
    {
        memset(mat,0,sizeof(mat));
    }

    void unit()
    {
        for(int i = 1; i <= 3; i++)
            mat[i][i]=1;
    }

    matrix operator *(matrix a)
    {
        matrix ans;
        for(int i = 1; i <= 3; i++)
            for(int j = 1; j <= 3; j++)
                for(int k = 1; k <= 3; k++)
                    ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*a.mat[k][j])%m;
        return ans; 
    }
}temp;
matrix fpow(matrix base, ll b)
{
    matrix r;
    r.unit();
    while(b)
    {
        if(b&1)
            r=r*base;
        base=base*base;
        b>>=1;
    }
    return r;
}
int main()
{
    ll n, p=10;
    scanf("%lld%lld",&n,&m);
    matrix f;
    f.mat[1][3]=1;
    for(int i = 1; i <= 3; i++)
        for(int j = 1; j <= i; j++)
            temp.mat[i][j]=1;
    while(n>=p)
    {
        temp.mat[1][1]=p%m;
        f=f*fpow(temp,p/10*9);
        p=p*10;
    }
    temp.mat[1][1]=p%m;
    f=f*fpow(temp,n-p/10+1);
    printf("%lld\n",f.mat[1][1]);
    return 0;   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值