题面
思路
Dp应该是比较显然的
F(N)
表示N的答案
k
表示N的位数
考虑矩乘优化
⎛⎝⎜F(N)N1⎞⎠⎟=⎛⎝⎜10k00110111⎞⎠⎟∗⎛⎝⎜F(N−1)N−11⎞⎠⎟
但是位数会有改变
可以将位数不同的几段分开矩乘
代码
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
char ch;
bool fl;
inline void read(int &a){
for(fl=0,ch=getchar();ch<'0'||ch>'9';ch=getchar()) fl^=(ch=='-');
for(a=0;ch>='0'&&ch<='9';ch=getchar())a=(a<<3)+(a<<1)+(ch^'0');
if(fl)a=-a;
}
const int S=3;
const int LOG=19;
ll N,K;
int Mods,k=0;
struct Matrix{
int p[S][S];
};
const Matrix First=(Matrix){{{1,0,0},{0,1,0},{0,0,1}}};
void Mul(Matrix &Ans,Matrix b){
Matrix a;
for(int i=0;i<S;i++)
for(int j=0;j<S;j++){
a.p[i][j]=Ans.p[i][j];
Ans.p[i][j]=0;
}
for(int i=0;i<S;i++)
for(int k=0;k<S;k++)
for(int j=0;j<S;j++){
Ans.p[i][j]+=(ll)a.p[i][k]*b.p[k][j]%Mods;
if(Ans.p[i][j]>=Mods)Ans.p[i][j]-=Mods;
}
}
Matrix Power(Matrix A,ll p){
Matrix Ans=First;
for(;p;p>>=1){
if(p&1)Mul(Ans,A);
Mul(A,A);
}
return Ans;
}
int main()
{
ll Pow[LOG];
Matrix Trans=(Matrix){{{1,1,1},{0,1,1},{0,0,1}}},Res=First,Ans;
Pow[0]=9;
for(int i=1;i<LOG;i++)Pow[i]=(Pow[i-1]+(Pow[i-1]<<2))<<1;
for(scanf("%lld%d",&N,&Mods);N;N-=K,k++){
K=min(N,Pow[k]);
Trans.p[0][0]+=Pow[k]%Mods;
if(Trans.p[0][0]>=Mods)Trans.p[0][0]-=Mods;
Ans=Power(Trans,K);
Mul(Ans,Res);
Res=Ans;
}
printf("%d",Res.p[0][2]);
return 0;
}