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 }
View Code

 

posted @ 2015-05-25 19:03  idy002  阅读(431)  评论(0编辑  收藏  举报