矩阵快速幂的学习

来源:互联网 发布:淘宝怎么看全五星评价 编辑:程序博客网 时间:2024/05/17 00:05

以下内容来自转载:

1:思想

矩阵快速幂的思想就是跟数的快速幂一样,假如我们要求2^11,次方,我们可以把 11 写成 1+2+8 ,也就是2^0 + 2^1 + 2^3 。那么把一个O(n)的时间复杂度降到了log(n)

矩阵快速幂的思想和数的快速幂是一模一样的,就是要自己实现矩阵的乘法,然后可以套数的快速幂的模板。


2:难点

矩阵题目的难点在于构造矩阵,一般用于有能够推出递推式的题目,推出递推式之后,发现递推O(n)的复杂度时间比较大,那么我们可以构造一个矩阵,然后用矩阵快速幂降低到log(n)的时间复杂度

快速幂模板:

[cpp] view plain copy
 print?
  1. #include <cstdio>  
  2. #include <string>  
  3. #include <cmath>  
  4. #include <iostream>  
  5. using namespace std;  
  6. const long long M = 1000007;  
  7. const long long N = 3;  
  8. long long t,b,c,f1,f2;  
  9. struct Node  //矩阵  
  10. {  
  11.     long long line,cal;  
  12.     long long a[N+1][N+1];  
  13.     Node(){  
  14.         line=3,cal=3;  
  15.         a[0][0] = b; a[0][1] = 1; a[0][2] = 0;  
  16.         a[1][0] = t; a[1][1] = 0; a[1][2] = 0;  
  17.         a[2][0] = c; a[2][1] = 0; a[2][2] = 1;  
  18.     }  
  19. };  
  20.   
  21. Node isit(Node x,long long c)  //矩阵初始化  
  22. {  
  23.     for(long long i=0;i<N;i++)  
  24.         for(long long j=0;j<N;j++)  
  25.             x.a[i][j]=c;  
  26.     return x;  
  27. }  
  28.   
  29. Node Matlab(Node x,Node s)  //矩阵乘法  
  30. {  
  31.     Node ans;  
  32.     ans.line = x.line,ans.cal = s.cal;  
  33.     ans=isit(ans,0);  
  34.     for(long long i=0;i<x.line;i++)  
  35.     {  
  36.         for(long long j=0;j<x.cal;j++)  
  37.         {  
  38.             for(long long k=0;k<s.cal;k++)  
  39.             {  
  40.                 ans.a[i][j] += x.a[i][k]*s.a[k][j];  
  41.                 ans.a[i][j]=(ans.a[i][j]+M)%M;  
  42.             }  
  43.         }  
  44.     }  
  45.     return ans;  
  46. }  
  47. long long Fast_Matrax(long long n)  //矩阵快速幂  
  48. {  
  49.     if(n==1)  
  50.         return f1;  
  51.     n-=2;  
  52.     long long x=1,f=n,ok=1;  
  53.     Node ans,tmp,ch;  
  54.     ans.line = 1,ans.cal = 3;  
  55.     ans.a[0][0] = f2, ans.a[0][1] = f1 ,ans.a[0][2] = 1;  
  56.     while(n>0)  
  57.     {  
  58.         if(n%2)  
  59.         {  
  60.             ans=Matlab(ans,tmp);  
  61.         }  
  62.         tmp=Matlab(tmp,tmp);  
  63.         n/=2;  
  64.     }  
  65.     return ans.a[0][0];  
  66. }  
  67. int main()  
  68. {  
  69.     long long n,T;  
  70.     scanf("%lld",&T);  
  71.     while(T--)  
  72.     {  
  73.         scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&t,&b,&c,&n);  
  74.         printf("%lld\n",Fast_Matrax(n));  
  75.     }  
  76.     return 0;  
  77. }  

0 0