Test instructions: Defines concatenate (1,n) =1234567......N. For example concatenate (1,13) = 12345678910111213. Given N and M, seek concatenate (1,n)%m. (1=<n<=10^18,1<=m<=10^9)
Idea: Make F[n] represent concatenate (1,n). Then there are:
f[i]=f[i-1]*10+ (i-1) +1 1<=i<=9
f[i]=f[i-1]*100+ (i-1) +1 10<=i<=99
......
Thus matrix acceleration can be used:
In this way, the matrix is quickly 1~9,10~99,100~999 by the number of bits. The structure of the matrix to pay attention to the details; the above two matrices are f,g; start from F0;
This is just fn=g^n*f0, and if it is g^ (n-1) *F1=FN, there will be an error in the segmentation process (think about it as much as possible).
and f0={0,0,1}, so fn=0*gn.m[0][0]+0*gn.m[0][1]+1*gn.m[2][0]=gn.m[2][0].
#include <cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<queue>#include<cstdlib>#include<vector>#include<Set>#include<map>#defineLL Long Long#defineINF 1<<30#defineN 100010using namespacestd;structmatrix{LL m[3][3];} Ans LL dig[ -],n,mod;matrix mult (Matrix A,matrix b) {matrix C; memset (C.M,0,sizeof(C.M)); for(intI=0;i<3; i++) for(intk=0;k<3; k++) { if(a.m[i][k]==0)Continue; for(intj=0;j<3; j + +) { if(b.m[k][j]==0)Continue; C.M[I][J]+=a.m[i][k]*b.m[k][j]%MoD; C.M[I][J]%=MoD; } } returnC;} Matrix Quickmod (Matrix A,ll n) {matrix temp; memset (temp.m,0,sizeof(temp.m)); for(intI=0;i<3; i++) temp.m[i][i]=1; while(n) {if(n&1) temp=mult (temp,a); A=mult (a,a); N>>=1; } returntemp;} Matrix Solve (LL n,ll t) {matrix x; x.m[0][0]=t%mod;x.m[0][1]=0; x.m[0][2]=0; x.m[1][0]=1; x.m[1][1]=1; x.m[1][2]=0; x.m[2][0]=1; x.m[2][1]=1; x.m[2][2]=1; returnQuickmod (x,n);}intMain () {dig[0]=1; for(intI=1; i<= -; i++) dig[i]=dig[i-1]*Ten; while(SCANF ("%lld%lld", &n,&mod)! =EOF) {memset (ANS.M,0,sizeof(ANS.M)); for(intI=0;i<3; i++) Ans.m[i][i]=1; for(intI=1;; i++) {LL left=dig[i-1]; LL Right=min (n,dig[i]-1); Ans=mult (Ans,solve (right-left+1, Dig[i])); if(right==n) Break; } printf ("%lld\n", ans.m[2][0]); }}View Code
Bzoj (Matrix fast Power)