[HNOI2011] 数学作业 题解

感触很深,写篇题解。

轻而易举地发现 \(dp\) 式:

\[dp_i=(dp_{i-1}\times 10^{1+\log_{10}i}\mod p+i)\mod p \]

时间复杂度 \(O(n)\),看来不行。

考虑矩阵快速幂优化。

有:

\[\begin{bmatrix}dp_i\ i+1\ 1\end{bmatrix}=\begin{bmatrix}dp_{i-1}\ i\ 1\end{bmatrix}\begin{bmatrix}10^{t}\ 0\ 0\\1\ \ \ \ 1\ 0\\0\ \ \ \ 1\ 1\end{bmatrix} \]

时间复杂度 \(O(\log_2n)\)

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
ull n,p;
struct mat{
    int x,y;
    ull z[4][4];
    mat(){
        for(int i=1;i<4;i++)
            for(int j=1;j<4;j++)
                z[i][j]=0;
    }
}a,b;
mat times(mat a,mat b){
    mat c;
    c.x=a.x;
    c.y=b.y;
    for(int i=1;i<=c.x;i++)
        for(int j=1;j<=c.y;j++)
            for(int k=1;k<=a.y;k++){
                c.z[i][j]+=a.z[i][k]*b.z[k][j]%p;
                c.z[i][j]%=p;
            }
    return c;
}mat qpow(mat a,mat b,ull x){
    while(x){
        if(x&1)
            a=times(a,b);
        b=times(b,b);
        x>>=1;
    }return a;
}int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>p;
    a.x=1,a.y=b.x=b.y=3;
    a.z[1][2]=a.z[1][3]=1;
    b.z[2][1]=b.z[2][2]=1;
    b.z[3][2]=b.z[3][3]=1;
    for(ull i=1,j=1;;i++){
        j=b.z[1][1]=j*10;
        b.z[1][1]%=p;
        if(n<j){
            a=qpow(a,b,n-(j/10-1));
            break;
        }a=qpow(a,b,j-j/10);
    }cout<<a.z[1][1];
    return 0;
}
posted @ 2024-03-11 21:22  长安一片月_22  阅读(4)  评论(0编辑  收藏  举报