快速幂指的是A = 1;矩阵快速幂指的是A=E, E为单位矩阵,即主对角线为1,其余为0;
快速幂:一般用long long ,且取余。
#include <iostream>
using namespace std;
#define mod 1e9 + 7
#define long long ll
ll quick_pow(int n, int base){//base^n
ll ans = 1;
ll multi = base;
while(n){
if(n % 2)// n & 1 || n % 2 ==
ans *= multi;
ans %= mod;
n /= 2;// n >> 1;效率高
multi *= multi;
multi %= mod;
}
return ans;
}作用:使用矩阵快速幂求递推式;例如斐波那契数列,求其第几项的值,范围到1e9,就需要用到矩阵快速幂。
斐波那契的定义是f(1)=f(2)=1; 然后f(n)=f(n-1)+f(n-2) (n>=2) 我们也可以这样定义f(1)=f(2)=1; [f(n),f(n-1)]=[f(n-1),f(n-2)][1,1,1,0],其中[1,1,1,0] 是一个2*2的矩阵 上面一行是1,1,下面一行是1,0,这样就可以化简了写成[f(n),f(n-1)]=[f(2),f(1)]*[1,1,1,0]^(n-2)。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define NUM 50
#define mod 1e9
int MAXN, n;
struct node {
int a[MUN][MUN];
void init(){
memset(a, 0, sizeof(a));
for(int i = 0; i < MAXN; ++i)
a[i][i] = 1;
}
}A;
Matrix mul(Matrix a, Matrix b){//矩阵乘法
Matrix ans;
for(int i = 0; i < MAXN; ++i){
for(int j = 0; j < MAXN; ++j){
ans.[i][j] = 0;
for(int k = 0; k < MAXN; ++k)
ans.a[i][j] += a.a[i][k] * b.a[k][j];
ans.a[i][j] % mod;
}
}
return ans;
}
Matrix add(Matrix a, Matrix b){//矩阵相加
Matrix ans;
for(int i = 0; i < MAXN; ++i){
for(int j = 0; j < MAXN; ++j){
ans.a[i][j] = a.a[i][j] + b.a[i][j];
ans.a[i][j] %= mod;
}
}
return ans;
}
Matrix pow(Matrix a, int n){//矩阵快速幂
Matrix ans;
ans.init;
while(n){
if(n & 1)
ans = mul(ans, a);
n >> 1;
a = mul(a, a);
}
return ans;
}
Matrix sum(Matrix a, int n){//矩阵求和
int m;
Matrix ans, pre;
if(n == 1)
return a;
m = (n >> 1);
pre = sum(a, m);//[1,n/2]
ans = add (pre, mul(pre, pow(a, m)));//ans=[1,n/2]+a^(n/2)*[1,n/2]
if(n & 1)
ans = add(ans, pow(a, n)); //ans=ans+a^n
return ans;
}
void output(Matrix a)//输出矩阵
{
for(int i=0;i<MAXN;i++)
for(int j=0;j<MAXN;j++)
printf("%d%c",a.a[i][j],j==MAXN-1?'\n':' ');
}
int main()
{
freopen("in.txt","r",stdin);
Matrix ans;
scanf("%d%d%d",&MAXN,&n,&mod);
for(int i=0;i<MAXN;i++)
for(int j=0;j<MAXN;j++)
{
scanf("%d",&A.a[i][j]);
A.a[i][j]%=mod;
}
ans=sum(A,n);
output(ans);
return 0;
}
1792

被折叠的 条评论
为什么被折叠?



