问题:
算法:矩阵加速
参考:https://blog.csdn.net/weixin_43501684/article/details/99739824
斐波那契数列矩阵加速分析:
另一个问题:
加速:
总结:当写出相关项的递推公式,便可以很容易写出加速矩阵。
矩阵快速幂
常数的快速幂算法:
int pow_mod(int a,int n,int m)
{//a的n次方取余m
if(n==0) return 1;
int x=pow_mod(a,n/2,m);
long long ans=(long long)x*x%m;
if(n%2==1) ans=ans*a%m;
return (int)ans;
}
将常数改为矩阵就好了,先定义矩阵乘法的方式。
盗取大佬的代码,
int n; // 所有矩阵都是 n * n 的矩阵
struct matrix {
int a[100][100];
};
matrix matrix_mul(matrix A, matrix B, int mod) {
// 2 个矩阵相乘
matrix C;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
C.a[i][j] = 0;
for (int k = 0; k < n; ++k) {
C.a[i][j] = (C.a[i][j] + A.a[i][k] * B.a[k][j] % mod) % mod;
}
}
}
return C;
}
matrix unit() {
// 返回一个单位矩阵
matrix res;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i == j) {
res.a[i][j] = 1;
} else {
res.a[i][j] = 0;
}
}
}
return res;
}
matrix matrix_pow(matrix A, int n, int mod) {
// 快速求矩阵 A 的 n 次方
matrix res = unit(), temp = A;
for (; n; n /= 2) {
if (n & 1) {
res = matrix_mul(res, temp, mod);
}
temp = matrix_mul(temp, temp, mod);
}
return res;
}
本题中给的矩阵:
某位博主给出的错误矩阵,提示你如何写正确的。
很简单:一行一列改为1.
盗取代码时的收获:
自己太菜了。
- strlen
2、memcpy
对数组
3.x&1和是二进制的按位与,与取余2相同。
4.x>>=1 与x/2相同。
盗取代码:
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int MOD=7777777,N=15;
ll a[N][N],f[N];
int n,m;
void mul(ll f[N],ll a[N][N])
{
ll c[N];
memset(c,0,sizeof(c));
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
c[i]=(c[i]+a[i][j]*f[j])%MOD;
memcpy(f,c,sizeof(c));
}
void mulself(ll a[N][N])
{
ll c[N][N];
memset(c,0,sizeof(c));
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=n;k++)
c[i][j]=(c[i][j]+a[i][k]*a[k][j])%MOD;
memcpy(a,c,sizeof(c));
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) a[1][i]=1;
for (int i=2;i<=n;i++) a[i][i-1]=1;
f[1]=1;
while (m)
{
if (m&1) mul(f,a);
mulself(a);
m>>=1;
}
printf("%d",f[1]);
return 0;
}