EOJ1499 矩阵快速幂

题目:

GaussAnd Fibonacci

 

TimeLimit:2000MS Memory Limit:30000KB

TotalSubmit:80 Accepted:38

 

Description

 

Weall know that 1+2+...+n=(1+n)*n/2;Gauss worked it out when he was a child!

Andwe also know the famous number sequence 1,1,2,3,5,8,13... named Fibonaccisequence.(F(1)=F(2)=1;when n>2,F(n)=F(n-1)+F(n-2);)

Ifwe put them togather,what thing will happen?

 

Input

 

Theinput will consist of a series of integers N, one integer per line.Process toend of file.(0<N<1000000000)

 

Output

 

Foreach case,calculate the sum of the Fibonacci numbers who's sequence number isnot bigger than N.Since it can be very huge,you should onle output the lasteight digits,do not output leading zeros(if the answer is 02007729,just output2007729).

 

SampleInput

 

6

 

SampleOutput

 

20

 

Hint:

1+1+2+3+5+8=20

 

Source

 

Modifiyfrom DYGG' problem

 

题目分析:

                   这题还是很考数学思维的。

              S[n-2]=f1+f2+f3+f4+……+fn-2;

              S[n-1]=f1+f2+f3+f4+f5+…fn-1;

              有s[n-1]+s[n-2]=f1+f3+f4+…+fn=s[n]-1;

              有s[n-1]+1+s[n-2]+1=s[n]+1;

              所以有s[n]+1为起点不同的费布拉切数列。观察得是s[n]+1=f(n+2)。难点主要在这个数列的推导上。根据f数列的性质,应该联想到错位相加的,之后利用矩阵快速幂即可算出答案。

 

 

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <string>

#include <vector>

#include <map>

#include <algorithm>

 

using namespace std;

 

struct Matrix

{

    long long a[2][2];

   Matrix(){memset(a,0,sizeof(a));}

};

 

Matrix operator*(const Matrix &a,const Matrix &b)              //矩阵乘法

{

    int i,j,k;

    Matrix c;

    for(i=0;i<2;++i)

        for(j=0;j<2;++j)

            for(k=0;k<2;++k)

            {

                c.a[i][j]=(c.a[i][j]+(a.a[i][k]*b.a[k][j])%100000000)%100000000;

            }

    return c;

}

 

Matrix quick_pow(int n)                        //矩阵快速幂

{

    Matrix ans,tem;

    ans.a[0][0]=ans.a[1][1]=1;

   tem.a[0][1]=tem.a[1][0]=tem.a[1][1]=1;

    while(n)

    {

        if(n&1)

            ans=ans*tem;

        tem=tem*tem;

        n>>=1;

    }

    return ans;

}

 

int main()

{

    int n;

   while(~scanf("%d",&n))

    {

        Matrix ans;

        ans=quick_pow(n+1);

       cout<<(ans.a[0][0]+ans.a[0][1]-1)%100000000<<endl;

    }

    return 0;

}

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值