HIT 2060 Fibonacci Problem Again(矩阵乘法)

本文介绍了一个基于斐波那契数列的算法题,通过矩阵快速幂的方法来高效解决大范围内的斐波那契数计算,并特别关注了在计算过程中涉及的大数取模操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:http://acm.hit.edu.cn/hoj/problem/view?id=2060

Fibonacci Problem Again

My Tags  (Edit)
  Source : HCPC 2005 FALL
  Time limit : 1 sec   Memory limit : 32 M

Submitted : 547, Accepted : 207

As we know , the Fibonacci numbers are defined as follows:

 """"

Given two numbers a and b , calculate . """"

Input

The input contains several test cases. Each test case consists of two non-negative integer numbers a and b (0 ≤ a ≤ b ≤1,000,000,000). Input is terminated by a = b = 0.

Output

For each test case, output S mod 1,000,000,000, since S may be quite large.

Sample Input

1 1
3 5
10 1000
0 0
Sample Output
1
16
496035733
关于取模的问题每步都要注意啊!!

#include <iostream>
#include <cstdio>
using namespace std;
const int mod=1e9;
typedef long long LL;
struct matrie{
    LL m[3][3];
};
matrie A={
    1,1,0,
    1,0,0,
    1,1,1
};
matrie I={
    1,0,0,
    0,1,0,
    0,0,1
};
matrie multi(matrie a,matrie b){
    matrie c;
    for(LL i=0;i<3;i++){
        for(LL j=0;j<3;j++){
            c.m[i][j]=0;
            for(LL k=0;k<3;k++){
                a.m[i][k]=a.m[i][k]%mod;
                b.m[k][j]=b.m[k][j]%mod;
                c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod;
            }
        }
    }
    return c;
}
matrie power(matrie a,LL k){
    matrie ans=I,tmp=a;
    while(k){
        if(k&1)ans=multi(ans,tmp);
        tmp=multi(tmp,tmp);
        k>>=1;
    }
    return ans;
}
int main()
{
    //freopen("cin.txt","r",stdin);
    int a,b;
    while(cin>>a>>b){
         if(a==0&&b==0) break;
         LL q1,q2;
         if(a==0)  q1=0;
         else if(a==1)  q1=1;
         else if(a==2)  q1=2;
         else if(a>2){
              matrie qs1=power(A,a-2);
              q1=(qs1.m[2][0]*1%mod+qs1.m[2][1]*1%mod+qs1.m[2][2]*2%mod)%mod;
         }

         if(b==0) q2=1;
         else if(b==1)  q2=2;
         else if(b>1){
              matrie qs2=power(A,b-1);
              q2=(qs2.m[2][0]*1%mod+qs2.m[2][1]*1%mod+qs2.m[2][2]*2%mod)%mod;
         }
         LL ans=(q2-q1+mod)%mod;
         cout<<ans<<endl;
    }
    return 0;
}
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值