学习笔记--矩阵相关

高斯消元

找出变量间关系

 - 高斯-约当消元法
#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)

posted @ 2018-05-20 17:19  Rye_Catcher  阅读(166)  评论(0编辑  收藏  举报