算法---矩阵的乘法及其运用

相信我们都做过一个题叫斐波那契数列,对于一般的题,n的取值范围通常在1000以内,但是如果你遇到的是下面这题呢?

斐波那契数列 - 洛谷

发现了吗?我的n取值范围连long long都会爆出,所以下面我们通过矩阵乘法和快速幂结合来解决该类问题,如果你不知道矩阵乘法和快速幂,这篇文章可能不适合你

下面我们利用矩阵乘法和快速幂来解决该问题:

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const ll p=1e9+7;
ll x;
const int N=2;
int n=2;
ll a[N+1][N+1],b[N+1];

void func1()
{
    ll m[N+1];
    memset(m,0,sizeof(m));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            m[i]+=b[j]*a[j][i];
            m[i]%=p;
        }
    }
    memcpy(b,m,sizeof(b));
}
void func2()
{
    ll w[N+1][N+1];
    memset(w,0,sizeof(w));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=n;k++)
            {
                w[i][j]+=a[i][k]*a[k][j];
                w[i][j]%=p;
            }
        }
    }
    memcpy(a,w,sizeof(a));
}
void quickpow(ll x)
{
    for(;x;x>>=1)
    {
        if(x&1)
        {
            func1();
        }
        func2();
    }
}
int main()
{
    //输入
    cin>>x;
    //快速幂+矩阵乘法
    //初始化
    a[1][1]=0;a[1][2]=1;
    a[2][1]=1;a[2][2]=1;
    b[1]=0;b[2]=1;
    quickpow(x-1);
    //输出
    cout<<b[2];
    return 0;
}

可以优化:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const ll p=1e9+7;
ll x;
const int N=2;
int n=2;
ll a[N+1][N+1],b[N+1];

void func1()
{
    ll m[N+1];
    memset(m,0,sizeof(m));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            m[i]+=b[j]*a[j][i];
            m[i]%=p;
        }
    }
    memcpy(b,m,sizeof(b));
}
void func2()
{
    ll w[N+1][N+1];
    memset(w,0,sizeof(w));
    for(int i=1;i<=n;i++)
    {
        for(int k=1;k<=n;k++)
        {
            if(a[i][k])
            {
                for(int j=1;j<=n;j++)
                {
                    if(a[k][j])
                    {
                        w[i][j]+=a[i][k]*a[k][j];
                        w[i][j]%=p;
                    }
                }
            }
        }
    }
    memcpy(a,w,sizeof(a));
}
void quickpow(ll x)
{
    for(;x;x>>=1)
    {
        if(x&1)
        {
            func1();
        }
        func2();
    }
}
int main()
{
    //输入
    cin>>x;
    //快速幂+矩阵乘法
    //初始化
    a[1][1]=0;a[1][2]=1;
    a[2][1]=1;a[2][2]=1;
    b[1]=0;b[2]=1;
    quickpow(x-1);
    //输出
    cout<<b[2];
    return 0;
}

下面我们给出矩阵乘法和快速幂结合模版,该类问题解题关机是构造矩阵

using ll = long long;
const ll N = 2;//实际情况修改
int n = 2;
ll a[N + 1][N + 1], b[N + 1];
const ll p = 1e8 + 7;//取模的值
void func1()
{
	ll m[N + 1];
	//清空
	memset(m, 0, sizeof(m));
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			m[i] += a[j][i] * b[j];
			m[i] %= p;
		}
	}
	memcpy(b, m, sizeof(b));
}
void func2()
{
	ll w[N + 1][N + 1];
	memset(w, 0, sizeof(w));
	/*for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			for (int k = 1; k <=n; k++)
			{
				w[i][j] += a[i][k] * a[k][j];
				w[i][j] %= p;
			}
		}
	}*/
	//优化:
	for (int i = 1; i <= n; i++)
	{
		for (int k = 1; k <= n; k++)
		{
			if (a[i][k])
			{
				for (int j = 1; j <= n; j++)
				{
					if (a[k][j])
					{
						w[i][j] += a[i][k] * a[k][j];
						w[i][j] %= p;
					}
				}
			}
		}
	}
	memcpy(a, w, sizeof(a));
}
void quickpow(ll x)
{
	for (; x; x >>= 1)
	{
		if (x & 1)
		{
			func1();
		}
		func2();
	}
}

关于这类问题,很多网址都有大量题目,大家可以自行去学习,感谢大家的支持!!!

相关推荐

  1. henauOJ 1084: 超简单矩阵乘法

    2024-03-27 12:04:01       38 阅读
  2. 矩阵运算:加减乘除与转置#matlab

    2024-03-27 12:04:01       6 阅读
  3. pytorch矩阵乘法

    2024-03-27 12:04:01       44 阅读
  4. 题目 2884: 矩阵乘法

    2024-03-27 12:04:01       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-27 12:04:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-27 12:04:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-27 12:04:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-27 12:04:01       20 阅读

热门阅读

  1. 常见的服务器技术

    2024-03-27 12:04:01       19 阅读
  2. python vtk并行渲染

    2024-03-27 12:04:01       21 阅读
  3. 电子元器件批发采购的数字化转型与技术应用

    2024-03-27 12:04:01       20 阅读
  4. BSP开发的内容

    2024-03-27 12:04:01       20 阅读
  5. easyexcel与vue配合下载excel

    2024-03-27 12:04:01       19 阅读
  6. LevelDB

    2024-03-27 12:04:01       17 阅读
  7. ChatGPT编程:让AI成为你的编程助手

    2024-03-27 12:04:01       19 阅读
  8. 软件设计师考试-设计模式速记

    2024-03-27 12:04:01       15 阅读
  9. 数据结构(四)链表实现队列和栈

    2024-03-27 12:04:01       20 阅读