矩阵
矩阵结构体
变量
a[N][N]:表示矩阵。其中 为自定义常数。h:行数。l:列数。
函数
clean():把结构体初始化。build():把结构体改成单位矩阵。若单位矩阵乘以某个 ,结果就是 。K_Recursion(k,*b):构造 阶常系数线性递推项, 是一个数组,构造的即是对于递推式 使 的矩阵 , 一般为 。
struct Juz{
long long a[N][N],h,l;
void clean(){
memset(a,0,sizeof a);
h=l=0;
}
long long & operator()(int x,int y){
return a[x][y];
}
void build(){
for(int i=1;i<N;++i)
a[i][i]=1;
}
void K_Recursion(int k,int *b){
clean();
h=l=k;
for(int i=1;i<=k;i++)
a[i][1]=b[i];
for(int i=1;i<k;i++)
a[i][i+1]=1;
}
};
矩阵加法
写法:a+b。
其中 都是 的矩阵结构体,返回值也是 的矩阵结构体。
Juz operator +(const Juz &x,const Juz &y){
Juz z;
z.clean();
z.h=x.h;z.l=x.l;
for(int i=1;i<=z.h;i++)
for(int j=1;j<=z.l;j++)
z.a[i][j]=x.a[i][j]+y.a[i][j];
return z;
}
矩阵减法
写法:a-b。
其中 都是 的矩阵结构体,返回值也是 的矩阵结构体。
Juz operator -(const Juz &x,const Juz &y){
Juz z;
z.clean();
z.h=x.h;z.l=x.l;
for(int i=1;i<=z.h;i++)
for(int j=1;j<=z.l;j++)
z.a[i][j]=x.a[i][j]-y.a[i][j];
return z;
}
矩阵乘法
写法:a*b。
其中 都是矩阵结构体,且 ,返回值是 的矩阵结构体。
答案矩阵的第 行第 列的数,就是由矩阵 第 行 个数与矩阵 第 列 个数分别相乘再相加得到的。
Juz operator *(const Juz &x,const Juz &y){
Juz z;
z.clean();
z.h=x.h;z.l=y.l;
for(int i=1;i<=x.h;++i)
for(int j=1;j<=y.l;++j)
for(int k=1;k<=x.l;++k)
z.a[i][j]+=x.a[i][k]*y.a[k][j];
//取模版
//z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
return z;
}
矩阵快速幂
写法:Juzqmi(a,k)。
矩阵乘法符合结合律,按普通快速幂计算即可。
返回值是 的矩阵结构体。
Juz Juzqmi(Juz a,long long k){
Juz ans;
ans.clean();
ans.build();
ans.h=a.h;ans.l=a.l;
while(k){
if(k&1)
ans=ans*a;
a=a*a;
k>>=1;
}
return ans;
}
矩阵求逆
将矩阵 的逆元存在 中,返回值为是否存在逆矩阵。
bool Juzinv(Juz &x,Juz &y){
y.clean();
y.h=x.h;y.l=x.l;
y.build();
for(int i=1;i<=x.h;i++){
for(int j=i;j<=x.h;j++){
if(x.a[j][i]){
for(int k=1;k<=x.l;k++)
swap(x.a[i][k],x.a[j][k]);
for(int k=1;k<=x.l;k++)
swap(y.a[i][k],y.a[j][k]);
break;
}
}
if(!x.a[i][i])return 0;
ll rate=qmi(x.a[i][i],mod-2);
for(int j=1;j<=x.l;j++){
x.a[i][j]=x.a[i][j]*rate%mod;
y.a[i][j]=y.a[i][j]*rate%mod;
}
for(int j=1;j<=x.h;j++){
if(i==j||!x.a[j][i])continue;
rate=x.a[j][i];
for(int k=1;k<=x.l;k++){
x.a[j][k]=(x.a[j][k]-rate*x.a[i][k]%mod+mod)%mod;
y.a[j][k]=(y.a[j][k]-rate*y.a[i][k]%mod+mod)%mod;
}
}
}
return 1;
}
行列式求值
ll det(){
ll f=1;
for(int i=1;i<=h;i++){
for(int j=i+1;j<=h;j++){
while(a[i][i]){
ll rate=a[j][i]/a[i][i];
for(int k=1;k<=h;k++){
a[j][k]=(a[j][k]-rate*a[i][k]%mod+mod)%mod;
swap(a[j][k],a[i][k]);
}
f*=-1;
}
for(int k=1;k<=h;k++)swap(a[j][k],a[i][k]);f*=-1;
}
}
f=(f+mod)%mod;
for(int i=1;i<=h;i++)f=f*a[i][i]%mod;
return f;
}
代码
//矩阵结构体
struct Juz{
long long a[N][N],h,l;
void clean(){
memset(a,0,sizeof a);
h=l=0;
}
void build(){
for(int i=1;i<N;++i)
a[i][i]=1;
}
void K_Recursion(int k,int *b){
clean();
h=l=k;
for(int i=1;i<=k;i++)
a[i][1]=b[i];
for(int i=1;i<k;i++)
a[i][i+1]=1;
}
};
//矩阵加法
Juz operator +(const Juz &x,const Juz &y){
Juz z;
z.clean();
z.h=x.h;z.l=x.l;
for(int i=1;i<=z.h;i++)
for(int j=1;j<=z.l;j++)
z.a[i][j]=x.a[i][j]+y.a[i][j];
return z;
}
//矩阵减法
Juz operator -(const Juz &x,const Juz &y){
Juz z;
z.clean();
z.h=x.h;z.l=x.l;
for(int i=1;i<=z.h;i++)
for(int j=1;j<=z.l;j++)
z.a[i][j]=x.a[i][j]-y.a[i][j];
return z;
}
//矩阵乘法
Juz operator *(const Juz &x,const Juz &y){
Juz z;
z.clean();
z.h=x.h;z.l=y.l;
for(int i=1;i<=x.h;++i)
for(int j=1;j<=y.l;++j)
for(int k=1;k<=x.l;++k)
z.a[i][j]+=x.a[i][k]*y.a[k][j];
//取模版
//z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
return z;
}
//矩阵快速幂,需要矩阵乘法
Juz Juzqmi(Juz a,long long k){
Juz ans;
ans.clean();
ans.build();
ans.h=a.h;ans.l=a.l;
while(k){
if(k&1)
ans=ans*a;
a=a*a;
k>>=1;
}
return ans;
}

浙公网安备 33010602011771号