超全斐波那契问题,快速幂,矩阵快速幂题集

本文介绍了如何使用矩阵快速幂算法高效地计算斐波那契数列,从简单的递归和迭代实现到矩阵快速幂的优化过程,包括斐波那契数列的前n项和以及特定条件下的斐波那契问题。通过实例展示了矩阵快速幂在解决这类问题中的优越性。
摘要由CSDN通过智能技术生成

PS:矩阵快速幂写疯了,没想到快速幂写着这么爽,哈哈哈哈哈哈哈~~


讲解还没来得及整理,有时间补上。

1.超超超简单斐波那契

题目链接

递归写法

class Solution {
public:
    int Fibonacci(int n) {
        if(n==0)return 0;
        if(n==1||n==2)return 1;
        return Fibonacci(n-1)+Fibonacci(n-2);
    }
};

迭代写法

class Solution {
public:
    int Fibonacci(int n) {
        int a[40];
        a[0]=0;
        a[1]=a[2]=1;
        for (int i = 3; i <= n; i ++ )
        a[i]=a[i-1]+a[i-2];
        return a[n];
    }
};

2.简单的斐波那契

范围在10^6以内,用动态数组存储

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
const int mod=1e9+7;
LL f[2]={0,1};
int main()
{
	
	int n;
   cin>>n;
   for(int i=2;i<=n;i++)
   {
   	f[i&1]=(f[i-1&1]+f[i&1])%mod;
   }
   if(n&1)cout<<f[1]<<endl;
   else cout<<f[0]<<endl;
   
}
3.矩阵快速幂的斐波那契

题目链接

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int mod = 10000;
int a[2][2];
void matrix_mul(int a[][2])
{
    int temp[2][2]={0};
    for(int i=0;i<2;i++)
      for(int j=0;j<2;j++)
         for(int k=0;k<2;k++)
             temp[i][j]=(temp[i][j]%mod+(LL)a[i][k]*a[k][j])%mod;
    memcpy(a,temp,sizeof temp);
}
void mul(int a[],int b[][2])
{
    int temp[2]={0};
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            temp[i]=(temp[i]+(LL)a[j]*b[j][i])%mod;
        }
    }
    memcpy(a,temp,sizeof temp);
}

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

4.矩阵快速幂斐波那契前n项和

题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
int n,m;
void mul(int a[],int b[][3]){
    int temp[3]={0};
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            temp[i]=(temp[i]+(LL)a[j]*b[j][i])%m;
    memcpy(a,temp,sizeof temp);        
}
void mul(int a[][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]+(LL)a[i][k]*a[k][j])%m;
                memcpy(a,temp,sizeof temp);
}
int main()
{
    cin>>n>>m;
    int f1[3]={1,1,1};
    int a[3][3]={
      {0,1,0},
      {1,1,1},
      {0,0,1}
    };
    n--;
    while(n){
        if(n&1)mul(f1,a);
        mul(a);
        n>>=1;
    }
    cout<<f1[2]<<endl;
    return 0;
}

5.佳佳的斐波那契

题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 4;
int n,m;
void mul(int c[][4],int a[][4],int b[][4]){
    static int t[4][4];
    memset(t, 0, sizeof t);
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            for(int k=0;k<4;k++)
                t[i][j]=(t[i][j]+(LL)a[i][k]*b[k][j])%m;
    memcpy(c,t,sizeof t);            
}
int main()
{
    cin>>n>>m;
    int f1[4][4]={1,1,1,0};
    int a[4][4]={
      {0,1,0,0},
      {1,1,1,0},
      {0,0,1,1},
      {0,0,0,1},
    };
    int k=n-1;
    while(k){
        if(k&1)mul(f1,f1,a);
        mul(a,a,a);
        k>>=1;
    }
    cout<<(((LL)n*f1[0][2]-f1[0][3])%m+m)%m<<endl;
}

6.矩阵加速

题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
const int mod = 1e9+7;
void mul_m(LL f[],LL a[][3])
{
    LL tmp[3]={0};
    for(int i=0;i<3;i++)
       for(int j=0;j<3;j++)
          tmp[i]=(tmp[i]+(LL)f[j]*a[j][i])%mod;
    memcpy(f,tmp,sizeof tmp);
}

void mul(LL a[][3])
{
    LL tmp[3][3]={0};
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
                tmp[i][j]=(tmp[i][j]+(LL)a[i][k]*a[k][j])%mod;
    memcpy(a,tmp,sizeof tmp);
}
int main()
{
   int m;
   cin>>m;
   while(m--)
   {
       LL n;
       cin>>n;
       LL f[3]={0,1,1};
       LL a[3][3]={
           {0,0,1},
           {1,0,0},
           {0,1,1}
       };
       while(n){
           if(n&1)mul_m(f,a);
           mul(a);
           n>>=1;
       }
       cout<<f[0]<<endl;
   }
}

7. Hdu5171 小奇的集合

不知道为啥在hdu代码过不了,但在下面链接里可以过,呜呜呜呜~~

题目链接

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
const int mod = 10000007;
void mul_m(LL f[],LL a[][3])
{
    LL tmp[3]={0};
    for(int i=0;i<3;i++)
       for(int j=0;j<3;j++)
          tmp[i]=(tmp[i]+(LL)f[j]*a[j][i])%mod;
    memcpy(f,tmp,sizeof tmp);
}

void mul(LL a[][3])
{
    LL tmp[3][3]={0};
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
                tmp[i][j]=(tmp[i][j]+(LL)a[i][k]*a[k][j])%mod;
    memcpy(a,tmp,sizeof tmp);
}
int main()
{
   LL n,k,x,res=0;
   cin>>n>>k;
   LL maxv1=-1e6,maxv2=-1e6;
   while(n--)
   {
       cin>>x;
       res=(res+x)%mod;
       if(x>maxv1)
       {
           maxv2=maxv1;
           maxv1=x;
       }
       else if(x>maxv2)maxv2=x;
   }
   LL f[3];
   
   if(maxv1<=0)
   {
       res+=(maxv1+maxv2)*k;
       res%=mod;
       cout<<res<<endl;
       return 0;
   }
   while(maxv2<0&&k)maxv2=(maxv2+maxv1)%mod,res=(res+maxv2)%mod,k--;
   
   
   f[0]=maxv2;
   f[1]=maxv1;
   res=(res-maxv1+mod)%mod;
   f[2]=res%mod;
   LL a[3][3]={
       {0,1,0},
       {1,1,1},
       {0,0,1}
   };
   while(k)
   {
     if(k&1)mul_m(f,a);
     mul(a);
     k>>=1;
   }
   cout<<((LL)(f[1]+f[2])%mod)<<endl;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_WAWA鱼_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值