矩阵相乘-斐波那契大数据版

原题链接

1≤n≤2000000000,
1≤m≤1000000010
数据的范围

* f1 = 1 , f2 = 1 , f3 = 2  , f4 = 3 ....
 f[i] = f[i - 1] + f[i - 2]
 然后 f[i] = f[i - 1] + f[i - 2] + f[i - 3] + ... f[1]
 普通的做法
 但是此题的范围比较大 所以需要用矩阵乘法来做

 fn = fn-1 + fn-2
Sn - Sn-1 = fn = fn-1 + fn-2 = sn-1 - sn-2 + sn-2 - sn-3 = sn-1 - sn-3
 sn - sn-1 = sn-1 - sn-3
 sn = 2sn-1 - sn-3

 求sn ?  sn = sn-1 * A  即 sn-1 * A  = sn 
 A = ? 
 s1 * An-1 = sn

 令 FN = {fn , fn+1 , sn};
  FN+1 = {fn+1 , fn+2, sn+1};
   
   FN * A = FN+1 所以 A = {0 1 0
                           1 1 1
                          0 0 1
                           };
*

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int n , m;

void mul(int a[] , int b[] , int c[][3])
{
    int temp[3] = {0};
    
    for(int i = 0 ; i < 3 ; i ++)
       for(int j = 0 ; j < 3 ; j ++)
          temp[i] = (temp[i] + (long long) b[j] * c[j][i]) % m;
          
    memcpy(a , temp , sizeof temp);
}

void mul(int a[][3] , int b[][3] ,int c[][3]) 
{
    int temp[3][3] = {0};
    
    for(int i = 0 ; i < 3 ; i ++)
        for(int j = 0 ; j < 3 ; j ++)
           for(int k = 0 ; k < 3 ; k ++)
             temp[i][j] = (temp[i][j] + (long long) b[i][k] * c[k][j]) % m;
             
    memcpy(a , temp , sizeof temp);
}

int main()
{
    cin >> n >> m;
    
    int a[][3] = { {0 , 1 , 0},
                   {1 , 1 , 1},
                   {0 , 0 , 1}
                 };
                 
    int f[] = {1 , 1 , 1};
    
    n --;
    while (n){
        if(n & 1) mul(f , f , a);
        n >>= 1;
        mul(a , a , a);
    }
    
    cout << f[2] << endl;
    
    return 0;
}

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值