ACM: 矩阵快速幂运算 数论题 poj 3…

来源:互联网 发布:提花组织软件 编辑:程序博客网 时间:2024/05/24 06:06
Fibonacci
Description

In the Fibonacci integersequence, F0 = 0, F1 = 1, andFn = 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

ACM: <wbr>矩阵快速幂运算 <wbr>数论题 <wbr>poj <wbr>3070.

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

Input

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

Output

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

Sample Input

0
9
999999999
1000000000
-1

Sample Output

0
34
626
6875

Hint

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

ACM: <wbr>矩阵快速幂运算 <wbr>数论题 <wbr>poj <wbr>3070.

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

ACM: <wbr>矩阵快速幂运算 <wbr>数论题 <wbr>poj <wbr>3070.

题意: 求斐波那契序列, 求出Fn % 10000, 题目给了一种新求法,矩阵求解斐波那契序列.

解题思路:
              1. ACM: <wbr>矩阵快速幂运算 <wbr>数论题 <wbr>poj <wbr>3070.
              2. 题目给出的矩阵乘积公式, 直接矩阵相乘求解O(n)算法超时.
              3. 但是我们知道矩阵相乘满足结合律. 例如:A^5 = A^2 * A^2 * A; 二分法 O(lgn);

代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

struct matrix
{
    intg[2][2];
};

int n;
matrix a;

matrix multiply(matrix A, matrix B,int m)
{
    matrixc;
    for(int i =0; i < 2; ++i)
    {
       for(int j =0; j < 2; ++j)
       {
          c.g[i][j] =0;
          for(int k =0; k < 2; ++k)
          {
             c.g[i][j] =(c.g[i][j] + A.g[i][k]*B.g[k][j])%m;
          }
       }
    }
    returnc;
}

matrix matrix_pow(matrix A, int n, int m)
{
    if(n == 1)return a;
    matrix temp= matrix_pow(A,n/2,m);
    matrix ans =multiply(temp,temp,m);
    if(n % 2 ==1) ans = multiply(ans,A,m);
    returnans;
}

int main()
{
    a.g[0][0] =1, a.g[0][1] = 1;
    a.g[1][0] =1, a.g[1][1] = 0;
//   freopen("input.txt","r",stdin);
   while(scanf("%d",&n) != EOF)
    {
       if(n == -1)break;
       if(n ==0)
       {
         printf("0\n");
         continue;
           
       else
       {
          matrixresult = matrix_pow(a,n,10000);
         printf("%d\n",result.g[0][1]);
       }
    }
    return0;
}

0 0
原创粉丝点击