3240: [noi2013] matrix game time limit: 10 sec memory limit: 256 MB
Submit: 613 solved: 256
[Submit] [Status] Description
Tingting is a matrix-loving child. One day she wants to use a computer to generate a huge N-Row M-column matrix (you don't have to worry about how she stores it ). The matrix she generated satisfies a magical nature: If f [I] [J] is used to represent the elements in column J of row I in the matrix, then f [I] [J] satisfies the following recursive formula:
F [1] [1] = 1
F [I, j] = A * f [I] [J-1] + B (J! = 1)
F [I, 1] = C * f [I-1] [m] + d (I! = 1)
In the recursive formula, A, B, C, and D are given constants.
Tingting wants to know the value of F [N] [M]. Please help her. Because the final result may be very large, you only need to output the remainder of F [N] [m] divided by 1,000,000,007.
Input
A row has six integers, n, m, A, B, C, and D. Meaning as described in
Output
Contains an integer that represents the remainder of F [N] [m] divided by 1,000,000,007.
Sample input3 4 1 3 2 6 sample output85hint
The matrix in the example is:
1 4 7 10
26 29 32 35
76 79 82 85
Based on the idea of refreshing questions before noip, I made this question with no data range. I found that the range of N and M is a little too much, and the decimal power is not enough, this question should be the ordinary O (N ^ 3) matrix multiplication. Since the second row of the matrix is not changed in the question, we can optimize the constant.
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MOD 1000000007#define MAXN 2100000typedef long long qword;struct matrix{ qword a[2][2]; int n,m; matrix() { memset(a,0,sizeof(a)); } void init0() { n=m=2; a[0][0]=a[1][1]=1; a[0][1]=a[1][0]=0; } void init1(int aa,int bb) { n=m=2; a[0][0]=aa; a[0][1]=bb; a[1][1]=1; } void init2(int aa) { n=2;m=1; a[0][0]=aa; a[1][0]=1; }};inline matrix operator *(matrix m1,matrix m2){ int i,j,k; matrix ret; ret.n=m1.n; ret.m=m2.m; if (ret.n==2 && ret.m==2) { if (m1.a[1][1]!=1 || m1.a[1][0]!=0 || m2.a[1][1]!=1 || m2.a[1][0]!=0) throw 1; ret.a[0][0]=m1.a[0][0]*m2.a[0][0]%MOD; ret.a[0][1]=(m1.a[0][0]*m2.a[0][1]%MOD+m1.a[0][1])%MOD; ret.a[1][0]=0; ret.a[1][1]=1; return ret; } for (i=0;i<m1.n;i++) { for (j=0;j<m2.m;j++) { for (k=0;k<m1.m;k++) { ret.a[i][j]=(ret.a[i][j]+m1.a[i][k]*m2.a[k][j]%MOD)%MOD; } } } return ret;}matrix pow_mod(matrix a,char *str,int len){ int i,j; register matrix t,l0,ret; ret.init0(); l0.init0(); t=a; for (i=len-1;i>=0;i--) { for (j=0;j<10;j++) { if (j==str[i]-‘0‘) ret=ret*l0; l0=l0*t; } t=l0; l0.init0(); } return ret;}char s1[MAXN],s2[MAXN];int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); qword a,b,c,d,i,j,k; scanf("%s %s%lld%lld%lld%lld",s1,s2,&a,&b,&c,&d); a%=MOD;b%=MOD;c%=MOD;d%=MOD; int l1,l2; l1=strlen(s1); l2=strlen(s2); int x; x=l1-1; s1[x]--; while (s1[x]<‘0‘) { s1[x]+=10;s1[x-1]--;x--; } x=l2-1; s2[x]--; while (s2[x]<‘0‘) { s2[x]+=10;s2[x-1]--;x--; } matrix m1,r1,m2,r2,r3,m3,r4,m4; matrix t1; m1.init1(a,b); m2.init1(c,d); m4.init2(1); r1=pow_mod(m1,s2,l2); r2=m2*r1; r3=pow_mod(r2,s1,l1); r4=r1*r3*m4; cout<<r4.a[0][0]<<endl;}
Bzoj 3240: [noi2013] matrix game matrix multiplication + decimal fast power + constant optimization