Bzoj2326 [HNOI2011]数学作业
Submit: 1819 Solved: 1074
Description
矩阵乘法会写不会用,悲伤
推出来递推式子是 f[i]=( f[i-1]*10^len[i]+i ) % mod
然后构造矩阵:
[ f[i] ] [ 10^len[i] 1 1 ] [ f[i-1] ]
[ i ] = [ 0 1 1 ] * [ i-1 ]
[ 1 ] [ 0 0 1 ] [ 1 ]
然而并不能出解。看了隔壁阿当的题解,发现运算的时候要改成这个样子:
[ f[i] 0 0 ]
[ 0 1 0 ]
[ 0 0 1 ]
然后出解是在(1,3)位置。
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #define LL long long 8 using namespace std; 9 const int mxn=100010; 10 LL n,mod; 11 struct mat{ 12 LL s[4][4]; 13 mat(){memset(s,0,sizeof s);} 14 }; 15 mat ans; 16 mat operator * (const mat a,const mat b){ 17 mat c; 18 for(int i=1;i<=3;i++) 19 for(int j=1;j<=3;j++) 20 for(int k=1;k<=3;k++){ 21 c.s[i][j]=(c.s[i][j]+a.s[i][k]*b.s[k][j])%mod; 22 } 23 return c; 24 } 25 inline void ksm(LL tmp,LL k){ 26 mat res; 27 res.s[1][1]=tmp%mod; 28 res.s[1][2]=res.s[1][3]=res.s[2][2]=res.s[2][3]=res.s[3][3]=1; 29 k=k-tmp/10+1; 30 while(k){ 31 if(k&1) ans=res*ans; 32 res=res*res; 33 k>>=1; 34 } 35 return; 36 } 37 int main(){ 38 int i,j; 39 scanf("%lld%lld",&n,&mod); 40 for(i=1;i<=3;i++) ans.s[i][i]=1; 41 LL t=10; 42 for(;t<=n;t*=10) 43 ksm(t,t-1); 44 ksm(t,n); 45 /* 46 for(i=1;i<=3;i++){ 47 for(j=1;j<=3;j++)printf("%d ",ans.s[i][j]); 48 printf("\n"); 49 } 50 */ 51 52 printf("%lld\n",ans.s[1][3]); 53 return 0; 54 }
本文为博主原创文章,转载请注明出处。