O(logN) 计算经典斐波那契数列的某个数

// O(logN) 时间复杂度
// 计算经典斐波那契数列的某个数
// 1 2 3 5 8 13 21 34 
// 如果只算一个数,二分很快 O(logn)
// 但如果全部输出,一个循环即可完成 O(n)
// 而不是二分计算每一个 

// 借助斐波那契矩阵
//                   1                   2                          n-1
// (f( n )) = ( 1 1 )  (f(n-1)) = ( 1 1 ) (f(n-2)) = ... =   ( 1 1 )   (f(2))
// (f(n-1))   ( 1 0 )  (f(n-2))   ( 1 0 ) (f(n-3))           ( 1 0 )   (f(1))
// 
// 这里计算 M的 a 次方 
// 也就是 M^(a/2)^2 
// 于是需要求 M^(a/2)
// 直到 M^1 
// 显然二分递归计算 
 
#include <stdio.h>
#define TYPE struct Fibo
#define X2(x) (x*x)
#define MAX_N 90

// 这里不拘泥于斐波那契矩阵的形式
// 而舍去了矩阵中一些不必要的东西
// (比如一直相等的数) 
// ( 3 2 ) ---> { 3, 2, 1 }
// ( 2 1 ) 
TYPE
{
    //int n;
    long long int a[3];
}F1={ {1, 1, 0} };
//TYPE Fi[MAX_N];

TYPE cheng(TYPE f, int flag)
{
    TYPE tf;
    if(flag==1) // *F1
    {
        tf.a[0]=f.a[0]+f.a[1];
        tf.a[1]=f.a[1]+f.a[2];
        tf.a[2]=f.a[1];
    }
    else if(flag==2) // *itself
    {
        tf.a[0]=X2(f.a[0])+X2(f.a[1]);
        tf.a[1]= f.a[0]*f.a[1]+f.a[1]*f.a[2];
        tf.a[2]=X2(f.a[1])+X2(f.a[2]);
    }
    return tf;
}
    
TYPE deal(int n)
{
    if(n<=1)return F1;
    if(n%2==1)
        return cheng(cheng(deal(n/2), 2), 1);
    else
        return cheng(deal(n/2), 2);
}
    
int main()
{
    int n=MAX_N;
    printf("F(%d) = %lld\n", n, deal(n).a[0]);
        
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值