以下内容来自转载:
1:思想
矩阵快速幂的思想就是跟数的快速幂一样,假如我们要求2^11,次方,我们可以把 11 写成 1+2+8 ,也就是2^0 + 2^1 + 2^3 。那么把一个O(n)的时间复杂度降到了log(n)
矩阵快速幂的思想和数的快速幂是一模一样的,就是要自己实现矩阵的乘法,然后可以套数的快速幂的模板。
2:难点
矩阵题目的难点在于构造矩阵,一般用于有能够推出递推式的题目,推出递推式之后,发现递推O(n)的复杂度时间比较大,那么我们可以构造一个矩阵,然后用矩阵快速幂降低到log(n)的时间复杂度
快速幂模板:
- #include <cstdio>
- #include <string>
- #include <cmath>
- #include <iostream>
- using namespace std;
- const long long M = 1000007;
- const long long N = 3;
- long long t,b,c,f1,f2;
- struct Node
- {
- long long line,cal;
- long long a[N+1][N+1];
- Node(){
- line=3,cal=3;
- a[0][0] = b; a[0][1] = 1; a[0][2] = 0;
- a[1][0] = t; a[1][1] = 0; a[1][2] = 0;
- a[2][0] = c; a[2][1] = 0; a[2][2] = 1;
- }
- };
-
- Node isit(Node x,long long c)
- {
- for(long long i=0;i<N;i++)
- for(long long j=0;j<N;j++)
- x.a[i][j]=c;
- return x;
- }
-
- Node Matlab(Node x,Node s)
- {
- Node ans;
- ans.line = x.line,ans.cal = s.cal;
- ans=isit(ans,0);
- for(long long i=0;i<x.line;i++)
- {
- for(long long j=0;j<x.cal;j++)
- {
- for(long long k=0;k<s.cal;k++)
- {
- ans.a[i][j] += x.a[i][k]*s.a[k][j];
- ans.a[i][j]=(ans.a[i][j]+M)%M;
- }
- }
- }
- return ans;
- }
- long long Fast_Matrax(long long n)
- {
- if(n==1)
- return f1;
- n-=2;
- long long x=1,f=n,ok=1;
- Node ans,tmp,ch;
- ans.line = 1,ans.cal = 3;
- ans.a[0][0] = f2, ans.a[0][1] = f1 ,ans.a[0][2] = 1;
- while(n>0)
- {
- if(n%2)
- {
- ans=Matlab(ans,tmp);
- }
- tmp=Matlab(tmp,tmp);
- n/=2;
- }
- return ans.a[0][0];
- }
- int main()
- {
- long long n,T;
- scanf("%lld",&T);
- while(T--)
- {
- scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&t,&b,&c,&n);
- printf("%lld\n",Fast_Matrax(n));
- }
- return 0;
- }