[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;
}