码迷,mamicode.com
首页 > 其他好文 > 详细

POJ_Fibonacci POJ_3070(矩阵快速幂入门题,附上自己写的矩阵模板)

时间:2015-06-14 18:30:35      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:

Fibonacci
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10521   Accepted: 7477

Description

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

An alternative formula for the Fibonacci sequence is

技术分享.

Given an integer n, your goal is to compute the last 4 digits of Fn.

Input

The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.

Output

For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).

Sample Input

0
9
999999999
1000000000
-1

Sample Output

0
34
626
6875

Hint

As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by

技术分享.

Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:

技术分享.

Source

 
 
解题报告:
矩阵快速幂直接求解即可。
 
附上我的矩阵模板:
typedef struct Matrix
{
  // Made by xiper , Last updata : 2015 / 6 / 14
  int r , c , ele[50][50];
  Matrix(const int & r , const int & c)
   {
      this->r = r , this->c = c;     // i will not init for ele , u should do it
   }
  friend ostream& operator << (ostream & os,const Matrix & x)
   {
         for(int i = 0 ; i < x.r ; ++ i)
          {
             for(int j = 0 ; j < x.c ; ++ j)
              os << x.ele[i][j] << " ";
          os << endl;    
       }
      return os;
   }
  Matrix operator * (const Matrix & x) const
   {
         if (c != x.r)
       {
          cout << "Error on Matrix operator * , (c1 != r1)" << endl;
          return Matrix(0,0);    
       }       
      Matrix res(r,x.c);
      for(int i = 0 ; i < r ; ++ i)
       for(int j = 0 ; j < x.c ; ++ j)
        {
           int sum = 0;
           for(int k = 0 ; k < c ; ++ k)
            sum += ele[i][k]*x.ele[k][j];
           res.ele[i][j] = sum;
        }
      return res;
   }
  Matrix operator * (const int & x ) const
   {
         Matrix res(r,c);
         for(int i = 0 ; i < r ; ++ i)
          for(int j = 0 ; j < c ; ++ j)
           res.ele[i][j] = ele[i][j]*x;
         return res;
   }
  Matrix operator + (const Matrix & x) const
   {
         if (x.r != r || x.c != c)
          {
             cout << "Error on Matrix operator + , (r1 != r2 || c1 != c2)" << endl;
          return Matrix(0,0);    
       }
      Matrix res(r,c);
      for(int i = 0 ; i < r ; ++ i)
       for(int j = 0 ; j < c ; ++ j)
        res.ele[i][j] = ele[i][j] + x.ele[i][j];
      return res;
   }
  Matrix operator - (const Matrix & x) const
   {
         if (x.r != r || x.c != c)
          {
             cout << "Error on Matrix operator + , (r1 != r2 || c1 != c2)" << endl;
          return Matrix(0,0);    
       }
      Matrix res(r,c);
      for(int i = 0 ; i < r ; ++ i)
       for(int j = 0 ; j < c ; ++ j)
        res.ele[i][j] = ele[i][j] - x.ele[i][j];
      return res;
   }
  void r_ope(int  whichr , int  num)
   {
         for(int i = 0 ; i < c ; ++ i)
          ele[whichr][i] += num;
   }
  void c_ope(int  whichc , int  num)
   {
         for(int i = 0 ; i < r ; ++ i)
          ele[i][whichc] += num;
   }
  void init(int x)
   {
         for(int i = 0 ; i < r ; ++ i)
          for(int j = 0 ; j < c ; ++ j)
           ele[i][j] = x;
   }
  void init_dig()
   {
         memset(ele,0,sizeof(ele));
         for(int i = 0 ; i < min(r,c) ; ++ i)
          ele[i][i] = 1;
   }
  Matrix Mulite (const Matrix & x ,int mod) const
   {
         if (c != x.r)
       {
          cout << "Error on Matrix function Mulite(pow may be) , (c1 != r1)" << endl;
          return Matrix(0,0);    
       }       
      Matrix res(r,x.c);
      for(int i = 0 ; i < r ; ++ i)
       for(int j = 0 ; j < x.c ; ++ j)
        {
           int sum = 0;
           for(int k = 0 ; k < c ; ++ k)
            sum += (ele[i][k]*x.ele[k][j]) % mod;
           res.ele[i][j] = sum % mod;
        }
      return res;
   }
  Matrix pow(int n , int mod)
   {
         if (r != c)
          {
             cout << "Error on Matrix function pow , (r != c)" << endl;    
             return Matrix(0,0);
       }
         Matrix tmp(r,c);
         memcpy(tmp.ele,ele,sizeof(ele));
         Matrix res(r,c);
         res.init_dig();
         while(n)
          {
             if (n & 1)
            res = res.Mulite(tmp,mod);
          n >>= 1;
          tmp = tmp.Mulite(tmp,mod);
       }
      return res;
   }
};

 

AC代码就不贴了(其实就几行。。)

POJ_Fibonacci POJ_3070(矩阵快速幂入门题,附上自己写的矩阵模板)

标签:

原文地址:http://www.cnblogs.com/Xiper/p/4575415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!