bzoj2326: [HNOI2011]数学作业
这个题就是很容易看出一个DP方程f[i]=f[i-1]*10^k+i
然后就分位数矩乘就可以了。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; LL n,mod,K10;int k; struct Matrix { LL mp[5][5]; }A,as; Matrix Matrix_cheng(Matrix a,Matrix b) { Matrix c; memset(c.mp,0,sizeof(c.mp)); for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) c.mp[i][j]=(c.mp[i][j]+a.mp[i][k]*b.mp[k][j])%mod; return c; } LL solve(LL f,int i) { K10*=10; A.mp[1][1]=K10%mod; A.mp[1][2]=0; A.mp[1][3]=0; A.mp[2][1]=1; A.mp[2][2]=1; A.mp[2][3]=0; A.mp[3][1]=1; A.mp[3][2]=1; A.mp[3][3]=1; as.mp[1][1]=f;as.mp[1][2]=(K10/10)%mod-1;as.mp[1][3]=1; if(i==1)as.mp[1][2]++; LL p=min(K10,n+1)-K10/10; if(i==1)p--; while(p!=0) { if(p%2==1)as=Matrix_cheng(as,A); A=Matrix_cheng(A,A);p/=2; } return as.mp[1][1]; } int main() { scanf("%lld%lld",&n,&mod); LL t=n;while(t!=0)k++, t/=10; LL f=1;K10=1; for(int i=1;i<=k;i++) f=solve(f,i); printf("%lld\n",f); return 0; }
pain and happy in the cruel world.