bzoj 3240 矩阵乘法+十进制快速幂
首先,构造出从f[][i]->f[][i+1]的转移矩阵a,和从f[i][m]->f[i+1][1]的转移矩阵b,
那么从f[1][1]转移到f[n][m]就是init*(a^(m-1)*b)^(n-1)*(a^(m-1))。
然后用用十进制快速幂(因为输入用的是10进制,这样就避免了高精度除法)。
第一次写十进制快速幂,大概的思想是维护当前位是1~9的要乘的矩阵,然后再通过这9个矩阵自己转移。
1 /************************************************************** 2 Problem: 3240 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:5352 ms 7 Memory:2764 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <cctype> 13 #include <algorithm> 14 #define N 1000010 15 #define Mod 1000000007 16 using namespace std; 17 18 typedef long long dnt; 19 struct Matrix { 20 dnt v[2][2]; 21 void make_unit() { 22 for( int i=0; i<2; i++ ) 23 for( int j=0; j<2; j++ ) 24 v[i][j] = (i==j); 25 } 26 inline const dnt* operator[]( int i ) const { return v[i]; } 27 Matrix(){} 28 Matrix( int aa, int ab, int ba, int bb ) { 29 v[0][0] = aa, v[0][1] = ab, v[1][0] = ba, v[1][1] = bb; 30 } 31 Matrix operator*( const Matrix &b ) const { 32 const Matrix &a = *this; 33 return Matrix( 1, (b[0][1]+a[0][1]*b[1][1])%Mod, 34 0, a[1][1]*b[1][1]%Mod ); 35 } 36 Matrix operator^( const char *b ) const { 37 Matrix rt, q[10]; 38 39 q[1] = *this; 40 for( int i=2; i<=9; i++ ) 41 q[i] = q[i-1]*q[1]; 42 43 rt.make_unit(); 44 for( int i=0; b[i]; i++ ) { 45 if( b[i]-'0' ) rt = rt*q[b[i]-'0']; 46 q[1] = q[1]*q[9]; 47 for( int j=2; j<=9; j++ ) 48 q[j] = q[j-1]*q[1]; 49 } 50 return rt; 51 } 52 }; 53 54 char sn[N], sm[N]; 55 int ln, lm; 56 int a, b, c, d; 57 Matrix ma, mb, ans; 58 59 void subone( char s[] ) { 60 int i = 0; 61 s[i]--; 62 while( s[i]<'0' ) { 63 s[i] += 10; 64 s[i+1]--; 65 i++; 66 } 67 } 68 int main() { 69 scanf( "%s%s%d%d%d%d", sn, sm, &a, &b, &c, &d ); 70 ln = strlen(sn), lm = strlen(sm); 71 reverse( sn, sn+ln ); 72 reverse( sm, sm+lm ); 73 subone(sn), subone(sm); 74 ma = Matrix(1,b,0,a)^sm; 75 mb = Matrix(1,d,0,c); 76 ans = ((ma*mb)^sn)*ma; 77 printf( "%lld\n", (ans[0][1]+ans[1][1]) % Mod ); 78 }