HDU 1005 Number Sequence:矩陣快速冪

Leohh發表於2017-08-18

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1005

題意:

  數列{f(n)}: f(1) = 1, f(2) = 1, f(n) = ( A*f(n-1) + B*f(n-2) ) MOD 7

  給定A、B、n,求f(n)。 (1<=n<=100,000,000)

 

題解:

  大水題~ (*/ω\*)

  矩陣快速冪。

  

  初始矩陣start:

  

  特殊矩陣special:

  

 

  所求矩陣ans:

    ans = start * special^(n-1)

  ans的第一項即為f(n)。

 

AC Code:

 

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #define MAX_L 5
  5 #define MOD 7
  6 
  7 using namespace std;
  8 
  9 struct Mat
 10 {
 11     int n;
 12     int m;
 13     int val[MAX_L][MAX_L];
 14     Mat()
 15     {
 16         n=0;
 17         m=0;
 18         memset(val,0,sizeof(val));
 19     }
 20 };
 21 
 22 int a,b,n;
 23 
 24 Mat make_unit(int n)
 25 {
 26     Mat mat;
 27     mat.n=n;
 28     mat.m=n;
 29     for(int i=0;i<n;i++)
 30     {
 31         mat.val[i][i]=1;
 32     }
 33     return mat;
 34 }
 35 
 36 Mat make_start()
 37 {
 38     Mat mat;
 39     mat.n=1;
 40     mat.m=2;
 41     mat.val[0][0]=1;
 42     mat.val[0][1]=1;
 43     return mat;
 44 }
 45 
 46 Mat make_special()
 47 {
 48     Mat mat;
 49     mat.n=2;
 50     mat.m=2;
 51     mat.val[0][0]=0;
 52     mat.val[0][1]=b;
 53     mat.val[1][0]=1;
 54     mat.val[1][1]=a;
 55     return mat;
 56 }
 57 
 58 Mat mul_mat(const Mat &a,const Mat &b)
 59 {
 60     Mat c;
 61     if(a.m!=b.n)
 62     {
 63         cout<<"Error: mat_mul"<<endl;
 64         return c;
 65     }
 66     c.n=a.n;
 67     c.m=a.m;
 68     for(int i=0;i<a.n;i++)
 69     {
 70         for(int j=0;j<b.m;j++)
 71         {
 72             for(int k=0;k<a.m;k++)
 73             {
 74                 c.val[i][j]+=a.val[i][k]*b.val[k][j];
 75                 c.val[i][j]%=MOD;
 76             }
 77         }
 78     }
 79     return c;
 80 }
 81 
 82 Mat quick_pow_mat(Mat mat,long long k)
 83 {
 84     Mat ans;
 85     if(mat.n!=mat.m)
 86     {
 87         cout<<"Error: quick_pow_mat"<<endl;
 88         return ans;
 89     }
 90     ans=make_unit(mat.n);
 91     while(k)
 92     {
 93         if(k&1)
 94         {
 95             ans=mul_mat(ans,mat);
 96         }
 97         mat=mul_mat(mat,mat);
 98         k>>=1;
 99     }
100     return ans;
101 }
102 
103 int main()
104 {
105     while(cin>>a>>b>>n)
106     {
107         if(a==0 && b==0 && n==0) break;
108         Mat start=make_start();
109         Mat special=make_special();
110         Mat ans=mul_mat(start,quick_pow_mat(special,n-1));
111         cout<<ans.val[0][0]<<endl;
112     }
113 }

 

相關文章