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

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

Stanford Local 2006

解题报告:

矩阵快速幂直接求解即可。

附上我的矩阵模板:

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代码就不贴了(其实就几行。。)

时间: 2024-08-28 03:47:14

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

矩阵快速幂(入门) 学习笔记hdu1005, hdu1575, hdu1757

矩阵快速幂是基于普通的快速幂的一种扩展,如果不知道的快速幂的请参见http://www.cnblogs.com/Howe-Young/p/4097277.html.二进制这个东西太神奇了,好多优秀的算法都跟他有关系,这里所说的矩阵快速幂就是把原来普通快速幂的数换成了矩阵而已,只不过重载了一下运算符*就可以了,也就是矩阵的乘法,  当然也可以写成函数,标题中的这三个题都是关于矩阵快速幂的基础题.拿来练习练习熟悉矩阵快速幂,然后再做比较难点的,其实矩阵快速幂比较难的是构造矩阵.下面还是那题目直接说话

HDU 1575 Tr A 【矩阵经典2 矩阵快速幂入门】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7572    Accepted Submission(s): 5539 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要

矩阵快速幂刷题系列

来源自http://blog.csdn.net/chenguolinblog/article/details/10309423 hdu 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5587    Accepted Submission(s): 4200 Problem Description A为一个方阵,则Tr

hdu 1575 Tr A(矩阵快速幂入门)

Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2977    Accepted Submission(s): 2217 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据. 每组数据的第一行有

Foj1683矩阵快速幂水题

Foj 1683 纪念SlingShot 题目链接:http://acm.fzu.edu.cn/problem.php?pid=1683 题目:已知 F(n)=3 * F(n-1)+2 * F(n-2)+7 * F(n-3),n>=3,其中F(0)=1,F(1)=3,F(2)=5,对于给定的每个n,输出F(0)+ F(1)+ -- + F(n) mod 2009.直接构造矩阵就好了,这个矩阵还是很好构造的. 求左边的矩阵矩阵的n-2次幂,和右边的矩阵想成就可以了. //Author: xiaow

poj 3070 矩阵快速幂简单题

基本运用,基本是模板题. 求fi[n].       (1,1)    *( 1  ) ( 1,0)     (  0) #include<iostream> #include<cstring> using namespace std; struct juz { int bat[3][3]; int x,y; //行 列 }; juz mutp(juz a,juz b) { juz c; c.x=a.x;c.y=b.y; memset(c.bat,0,sizeof(c.bat));

hdu 2604 Queuing(矩阵快速幂乘法)

Problem Description Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time. Now we define that ‘f’ is short for female and

HDU 2604 Queuing (矩阵快速幂)

HDU 2604 Queuing (矩阵快速幂) ACM 题目地址:HDU 2604 Queuing 题意: n个人排队,f表示女,m表示男,包含子串'fmf'和'fff'的序列为O队列,否则为E队列,有多少个序列为E队列. 分析: 矩阵快速幂入门题. 下面引用巨巨解释: 用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1): 如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff

BZOJ 2510: 弱题( 矩阵快速幂 )

每进行一次, 编号为x的数对x, 和(x+1)%N都有贡献 用矩阵快速幂, O(N3logK). 注意到是循环矩阵, 可以把矩阵乘法的复杂度降到O(N2). 所以总复杂度就是O(N2logK) ---------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; const int maxn = 1009; int N, M, K,