首页 > 代码库 > 矩阵快速幂模板篇
矩阵快速幂模板篇
转载请注明出处:http://blog.csdn.net/u012860063
或许你们看不太懂,纯属自用;
第一种:
Description
Let‘s define another number sequence, given by the following function:
f(0) = a
f(1) = b
f(n) = f(n-1) + f(n-2), n > 1
When a = 0 and b = 1, this sequence gives the Fibonacci sequence. Changing the values of a and b, you can get many different sequences. Given the values of a, b, you have to find the last m digits of f(n).
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each test case consists of a single line containing four integers a b n m. The values of a and b range in [0,100], value of n ranges in [0, 109] and value of m ranges in [1, 4].
Output
For each case, print the case number and the last m digits of f(n). However, do NOT print any leading zero.
Sample Input
4
0 1 11 3
0 1 42 4
0 1 22 4
0 1 21 4
Sample Output
Case 1: 89
Case 2: 4296
Case 3: 7711
Case 4: 946
代码如下:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; struct A { int mat[2][2]; }; A d,f; int n,mod; A mul(A a,A b) { A t; memset(t.mat,0,sizeof(t.mat)); for(int i=0;i<n;i++) { for(int k=0;k<n;k++) { if(a.mat[i][k]) for(int j=0;j<n;j++) { t.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; t.mat[i][j]%=mod; } } } return t; } A quickP(int k) { A p = d ,m; memset(m.mat,0,sizeof(m.mat)); for(int i=0;i<n;++i)//单位矩阵 { m.mat[i][i]=1; } /*if(k==0) return e;*/ while(k) { if(k & 1) m=mul(m,p); p=mul(p,p); k >>= 1 ; } return m; } int main() { n=2; int k,t;int x,y,z,w; while(scanf("%d",&t)!=EOF) { int s=0; while(t--) { scanf("%d%d%d%d",&x,&y,&z,&w); mod=1; d.mat[1][1]=0; d.mat[0][0]=d.mat[1][0]=d.mat[0][1]=1; for(int i = 1 ; i <= w ; i++) mod*=10; A ret=quickP(z-1);//z-1 乘的次数 int ans=(ret.mat[0][0]*y%mod+ret.mat[0][1]*x%mod)%mod; printf("Case %d: %d\n",++s,ans); } } return 0; }
Description
You have to find the nth term of the following function:
f(n) = a * f(n-1) + b * f(n-3) + c, if(n > 2)
= 0, if(n ≤ 2)
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case contains four integers n (0 ≤ n ≤ 108),a b c (1 ≤ a, b, c ≤ 10000).
Output
For each case, print the case number and f(n) modulo 10007.
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; struct Matrix { int m[5][5]; }I,A,T; int a,b,n,mod; Matrix matrixmul(Matrix a,Matrix b) { int i,j,k; Matrix c; for (i=1;i<=4;i++) for(j=1;j<=4;j++) { c.m[i][j]=0; for(k=1;k<=4;k++) { c.m[i][j]+=(a.m[i][k]*b.m[k][j]); c.m[i][j]%=10007; } } return c; } Matrix quickpagow(int n) { Matrix m=A,b=I; while (n>=1) { if(n&1) b=matrixmul(b,m); n=n>>1; m=matrixmul(m,m); } return b; } int main() { int t,ans,i,flag=1,a,b,c; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&n,&a,&b,&c); memset(I.m,0,sizeof(I.m)); memset(A.m,0,sizeof(A.m)); for(i=1;i<=4;i++) { I.m[i][i]=1; } A.m[1][1]=a,A.m[1][2]=0,A.m[1][3]=b,A.m[1][4]=c; A.m[2][1]=A.m[3][2]=A.m[4][4]=1; if(n>=3) { T=quickpagow(n-2); ans=0; printf("Case %d: %d\n",flag++,T.m[1][4]%10007); } else printf("Case %d: %d\n",flag++,0); } return 0; }