【矩阵】

实战 

将矩阵乘法封装在结构体里炒鸡好用

矩阵A×B

给定两个相容的矩阵A和B,即A的列数与B的行数相等,如果A= (aik)是一个mXn的矩阵,并且B=(bkj)是一个nXp矩阵,那么它们的积C=AB是一个mXp矩阵C=(cij)

其中,对于i=1,2,...,m  j=1,2,...,p'       

nXm矩阵A乘mXp矩阵B

for(int i=1;i<=n;++i)
for(int j=1;j<=p;++j)
for(int k=1;k<=m;++k)
c[i][j]+=a[i][k]*b[k][j];

 Fibonacci第n项

P1962 斐波那契数列

f[i]=1Xf[i-1]+1Xf[i-2] f[i-1]=1Xf[i-1]+0Xf[i-2]得到.......

#include<bits/stdc++.h>
#define ll long long const int N=100+5,M=100+5,P=1000000007,INF=1e9+7,inf=0x3f3f3f3f; ll n,m; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } struct Maxtrix{ int a[3][3]; Maxtrix(){memset(a,0,sizeof(a));} Maxtrix operator*(const Maxtrix &b)const{ Maxtrix res; for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k) res.a[i][j]=(res.a[i][j]+(ll)a[i][k]*b.a[k][j])%P; return res; } }ans,base; void qmul(ll b){ while(b){ if(b&1) ans=ans*base; base=base*base,b>>=1; } } int main(){ // freopen("in2.txt","r",stdin); rd(n); if(n<=2) return puts("1"),0; base.a[1][1]=base.a[1][2]=base.a[2][1]=1; ans.a[1][1]=ans.a[1][2]=1; qmul(n-2); printf("%d",ans.a[1][1]); return 0; }

 Fibonacci前n项和

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=100+5,M=100+5,P=1000000007,INF=1e9+7,inf=0x3f3f3f3f;
ll n,m;
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct Maxtrix{
    ll a[4][4];
    Maxtrix(){memset(a,0,sizeof(a));}
    Maxtrix operator*(const Maxtrix &b)const{
        Maxtrix res;
        for(int i=1;i<=3;++i)
        for(int j=1;j<=3;++j)
        for(int k=1;k<=3;++k)
        res.a[i][j]=(res.a[i][j]+(ll)a[i][k]*b.a[k][j])%m;
        return res;
    }
}ans,base;

void qmul(ll b){
    while(b){
        if(b&1) ans=ans*base;
        base=base*base,b>>=1;
    }
}

int main(){
 //   freopen("in2.txt","r",stdin);
     rd(n),rd(m);
     if(n==1) return puts("1"),0;
     if(n==2) return puts("2"),0;
     base.a[1][1]=base.a[2][1]=base.a[2][2]=base.a[2][3]=base.a[3][2]=1;
     ans.a[1][1]=ans.a[1][2]=ans.a[1][3]=1;
     qmul(n-1);
     printf("%lld",ans.a[1][1]);
    return 0;
}

佳佳的Fibonacci

求T(n)=1×f[1]+2×f[2]+...+n×f[n]

emmmm这三道题都一个套路 推出递推公式 然后用矩阵快速幂做

#includeM=<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5,M=100+5,P=1e8,INF=1e9+7,inf=0x3f3f3f3f;
ll n,m;
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct Maxtrix{
    int a[N][N];
    Maxtrix(){memset(a,0,sizeof(a));}
    Maxtrix operator*(const Maxtrix &b)const{
        Maxtrix c;
        for(int i=1;i<N;++i)
        for(int j=1;j<N;++j)
        for(int k=1;k<N;++k)
        c.a[i][j]=(c.a[i][j]+(ll)a[i][k]*b.a[k][j])%m;
        return c;
    }
}ans,base;

void qmul(int b){
    while(b){
        if(b&1) ans=base*ans;
        base=base*base,b>>=1;
    }
}

int main(){
 //   freopen("in2.txt","r",stdin);
     rd(n),rd(m);
     if(n==1) return puts("1"),0;
     if(n==2) return puts("3"),0;
     base.a[1][1]=base.a[1][2]=base.a[2][2]=base.a[2][3]=base.a[3][3]=base.a[3][4]=base.a[4][3]=1;
     ans.a[2][1]=ans.a[3][1]=ans.a[4][1]=1;
    qmul(n-1);
     printf("%d",(-ans.a[1][1]+(ll)n*ans.a[2][1]+m)%m);
    return 0;
}

......不想写了

其实吧,我觉得不用死记矩阵乘法的规则,你只用弄清楚你拿来干什么,然后根据你要搞的东西来写就是了

前置(我只是截图下来好玩)

from算法导论矩阵部分

概念

正方形nXn矩阵非常常见。我们通常对方阵的几个特例感兴趣。

 1.若一个矩阵中对于任意i≠j,均有a,=0,则该矩阵是一个对角矩阵。因为对角矩阵的非对角元素均为0,所以只需要列出其对角线上的元素就可以表示一个对角矩阵:

2.称对角线元素均为1的nXn对角矩阵为nXn单位矩阵In :

单位矩阵的第i列是单位向量ei.

矩阵基本操作

 

猜你喜欢

转载自www.cnblogs.com/lxyyyy/p/11342844.html