POj 3070Fibonacci(矩阵快速幂)

来源:互联网 发布:steam邮箱数据渠道 编辑:程序博客网 时间:2024/06/03 15:27
Fibonacci
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 15458 Accepted: 10837

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

099999999991000000000-1

Sample Output

0346266875

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
传送门:好的博客讲解点击打开链接
想法:矩阵快速幂

矩阵乘法和快速幂
代码一:
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod=10000;
ll A[2][2],B[2][2],T[2][2];
void pow(int n)//求第n个的斐波拉契数
{
    if(n==0)
    {
        //for(int i=0;i<2;i++)
            //for(int j=0;j<2;j++)
               // B[i][j]=(i==j);
        B[0][0]=1;B[0][1]=0;B[1][0]=0;B[1][1]=1;
        return;
    }


    if(n&1)
    {
        pow(n-1);
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
            {
                T[i][j]=0;
                    for(int k=0;k<2;k++)
                        T[i][j]=(T[i][j]+A[i][k]*B[k][j])%mod;
            }
       for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
            {
                B[i][j]=T[i][j];
            }


    }
    else
    {
        pow(n/2);
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
            {
                T[i][j]=0;
                for(int k=0;k<2;k++)
                    T[i][j]=(T[i][j]+B[i][k]*B[k][j])%mod;
            }
       for(int i=0;i<2;i++)
          for(int j=0;j<2;j++)
            {
                B[i][j]=T[i][j];
            }
    }
}
int main()
{
  int n;
  A[0][0]=1; A[0][1]=1;
  A[1][0]=1; A[1][1]=0;
  while (scanf("%d", &n)&& n!=-1)
  {
        ll ans;
        if(n==0)
        {
            printf("0\n");
            continue;
        }
        pow(n-1);
        ans=B[0][0]%mod;
        if(ans<0) ans+=mod;
        //printf("%lld\n",B[0][0]);
        printf("%lld\n",ans);
  }


  return 0;
}
代码二:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define Mod 10000
struct node
{
    int v[3][3];
    int m,l;//l为列数,m位行数
};
node get_mul(node a,node b)
{
    node c;
    c.m=a.m;c.l=b.l;
    for(int i=1;i<=c.m;i++)
      for(int j=1;j<=c.l;j++)
      {
          c.v[i][j]=0;
          for(int k=1;k<=a.l;k++)
              c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%Mod;
      }
    return c;
}


int main()
{
    int n;
    while(scanf("%d",&n)&&n!=-1)
    {
        if(n==0)
            {printf("0\n");continue;}
        node a,b,c;
        a.m=a.l=2,a.v[1][1]=1,a.v[1][2]=1,a.v[2][1]=1,a.v[2][2]=0;
        b.m=b.l=2,b.v[1][1]=1,b.v[1][2]=0,b.v[2][1]=0,b.v[2][2]=1;
        c.m=2,c.l=1,c.v[1][1]=1,c.v[2][1]=0;
        n--;
        while(n)
        {
            if(n&1) b=get_mul(a,b);
            a=get_mul(a,a);
            n>>=1;
        }
        b=get_mul(b,c);
        printf("%d\n",b.v[1][1]);
    }
    return 0;
}