学习笔记--矩阵相关

高斯消元

找出变量间关系

  • 模板

    • 高斯-约当消元法
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <cmath>
using namespace std;
const int maxn=103;
const double eps=1e-8;
int n;
double a[maxn][maxn],b[maxn];//a--系数 b--常数 
inline bool gs(){
    double rate;
    for(register int i=1;i<=n;i++){//消元 
        int k=i;
        for(register int j=i+1;j<=n;j++)
           if(fabs(a[j][i])>fabs(a[k][i]))k=j;//选取最大做主元防止误差 
        if(fabs(rate=a[k][i])<eps)return 0;//主元无系数 无解 
        for(register int j=i;j<=n;j++)swap(a[i][j],a[k][j]);//将主元那一行换到第i行来 
        swap(b[i],b[k]); 
        for(register int j=i;j<=n;j++)a[i][j]=a[i][j]/rate;//将主元系数化为1 
        b[i]=b[i]/rate;
        for(register int k=1;k<=n;k++){
            if(k==i)continue;
            rate=a[k][i];
            for(int j=i;j<=n;j++)a[k][j]=a[k][j]-a[i][j]*rate;
            b[k]=b[k]-b[i]*rate;
        }
    }
    return 1;
}
int main(){
    scanf("%d",&n);
    for(register int i=1;i<=n;i++){
        for(register int j=1;j<=n;j++){
            scanf("%lf",&a[i][j]); 
        }
        scanf("%lf",&b[i]);
    }
    if(gs()==1){
        for(register int i=1;i<=n;i++)printf("%.2lf\n",b[i]);
    }
    else{
        puts("No Solution");
    }
    return 0;
}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cctype>
using namespace std;
const int maxn=13;
const double eps=1e-8;
double a[maxn][maxn],b[maxn][maxn],c[maxn];
int n;
inline void gs(){
    double rate;
    int mx;
    for(register int i=1;i<=n;i++){
        mx=i;
        for(register int j=i+1;j<=n;j++){
            if(fabs(b[j][i])>fabs(b[mx][i]))mx=j;
        }
        //if(fabs(rate=b[mx][i])<eps)return ;
        rate=b[mx][i];
        for(register int j=i;j<=n;j++){
            swap(b[i][j],b[mx][j]);
        }
        swap(c[i],c[mx]);
        for(register int j=i;j<=n;j++)b[i][j]=b[i][j]/rate;
        c[i]=c[i]/rate;
        for(register int k=1;k<=n;k++){
            if(k==i)continue;
            rate=b[k][i];
            for(register int j=i;j<=n;j++)b[k][j]=b[k][j]-b[i][j]*rate;
            c[k]=c[k]-c[i]*rate;
        }
    }
    return ;
}
int main(){
    scanf("%d",&n);
    for(register int i=1;i<=n+1;i++){
        for(register int j=1;j<=n;j++){
            scanf("%lf",&a[i][j]);
        }
    }
    for(register int i=1;i<=n;i++){
        for(register int j=1;j<=n;j++){
            b[i][j]=2*(a[i][j]-a[i+1][j]);  
            c[i]+=a[i][j]*a[i][j]-a[i+1][j]*a[i+1][j];
        }
    }
    gs();
    for(register int i=1;i<=n;i++){
        printf("%.3lf ",c[i]);
    }
    return 0;
}
 

线性基

  • 待填坑

矩阵加速递推

关键构造友矩阵

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#define ll long long 
using namespace std;
const int maxn=107;
const long long p=1000000007;
struct Matrix{
    int n,m;
    ll ma[maxn][maxn];
    Matrix(int rk){n=m=rk;for(register int i=1;i<=rk;i++)ma[i][i]=1;}
    Matrix(int rk_n,int rk_m){n=rk_n,m=rk_m;}
    Matrix(){;}
    Matrix operator *(const Matrix &x)const{
       Matrix c=Matrix(n,x.m);
       for(register int i=1;i<=n;i++){
        for(register int j=1;j<=x.m;j++){
            ll tmp=0;
            for(register int k=1;k<=m;k++){
                tmp+=ma[i][k]*x.ma[k][j];
                if(tmp>19260817)tmp=tmp%p;
               }
            c.ma[i][j]=tmp;
           }
       }
       return c;    
    }
    Matrix operator ^(const int &C)const{
        int c=C;
        Matrix ans=Matrix(n);
        Matrix res=*this;
        while(c){
            if(c&1){ans=ans*res;}
            res=res*res;
            c=c>>1;
        }
        return ans;
    }
    Matrix operator ^(const ll &C)const{
        ll c=C;
        Matrix ans=Matrix(n);
        Matrix res=*this;
        while(c){
            if(c&1){ans=ans*res;}
            res=res*res;
            c=c>>1;
        }
        return ans;
    }
};
int main(){
    ll n;
    Matrix f0(2,1);f0.ma[1][1]=1,f0.ma[2][1]=1;
    Matrix A(2);A.ma[1][1]=1,A.ma[1][2]=1,A.ma[2][1]=1,A.ma[2][2]=0;
    scanf("%lld",&n);
    if(n<=2){
        cout<<1<<endl;
        return 0;
    }
    //Matrix ans=mul(Matrix_ksm(A,n),f0);
    //Matrix ans=(A^(n-1))*f0;
    A=A^(n-1);
    Matrix ans=f0*A;
    printf("%lld\n",ans.ma[1][1]);
    return 0; 
}
 
  • 简单变式

    ####注意!!!矩阵定义中一定要加memset,否则可能有非0元素,太恶心了

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cmath>
#define ll long long 
const ll p=1000000007;
const int maxn=15;
int t;
struct Matrix{
    int n,m;
    ll ma[maxn][maxn];//注意!!!!一定要memset 
    Matrix(int _n){n=m=_n;memset(ma,0,sizeof(ma));for(register int i=1;i<=n;i++)ma[i][i]=1;}
    Matrix(int _n,int _m){n=_n,m=_m;}
    Matrix(){;}
    Matrix operator *(const Matrix& b)const {
        Matrix c=Matrix(n,b.m);
        for(register int i=1;i<=n;i++){
          for(register int j=1;j<=b.m;j++){
            ll tmp=0;
            for(register int k=1;k<=m;k++){
                tmp+=ma[i][k]*b.ma[k][j];
                if(tmp>19260817)tmp=tmp%p;
              }
            c.ma[i][j]=tmp;
          }
       }
          return c;
    }
    Matrix operator ^(const int &C)const {
        int c=C;
        Matrix ans=Matrix(n);
        Matrix res=*this;
        while(c){
            if(c&1)ans=ans*res;
            res=res*res;
            c=c>>1;
        }
        return ans;
    }
    Matrix operator ^(const ll &C)const {
        ll c=C;
        Matrix ans=Matrix(n);
        /*for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++)printf("%lld ",ans.ma[i][j]);
            puts("");
            }*/
        Matrix res=*this;
        while(c){
            if(c&1)ans=ans*res;
            res=res*res;
            c=c>>1;
            
        }
        return ans;
    }
};
int main(){
    ll n;
    scanf("%d",&t);
    while(t--){
        scanf("%lld",&n);
        if(n<=3){puts("1");continue;}
        Matrix A=Matrix(3,3);
        A.ma[1][1]=1;A.ma[1][2]=0;A.ma[1][3]=1;
        A.ma[2][1]=1;A.ma[2][2]=0;A.ma[2][3]=0;
        A.ma[3][1]=0;A.ma[3][2]=1;A.ma[3][3]=0;
        Matrix f0=Matrix(3,1);
        f0.ma[1][1]=1,f0.ma[2][1]=1,f0.ma[3][1]=1;
        A=A^(n-1);
        //std::cout<<'*'<<A.ma[1][1]<<std::endl;
        /*for(int i=1;i<=3;i++){
         for(int j=1;j<=3;j++)printf("%lld ",A.ma[i][j]);
         puts("");
        }*/
        f0=f0*A;
        printf("%lld\n",f0.ma[1][1]);
    }
    return 0;
}

矩阵树定理(Matrix-Tree)

猜你喜欢

转载自www.cnblogs.com/Rye-Catcher/p/9063927.html
今日推荐