Matrix Power Series

Description

Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

Analysis

一道矩阵背景下的简单sumdiv,同样是两种算法。

  • 等比数列

ans=A^ k+1 / A-1

好像很简单,但是要用到矩阵除法,即矩阵逆元,我目前不会..

  • 拆分子问题

当k为偶数时,原式就等于(A^ k/2 +1)(A1+A2+...+A^k/2),这样就拆分出了子问题,可以用快速幂解决,至于奇数..把最后一个拎出来就行。

Code

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
const int N=110;
int n,MOD;
class Matrix{
	private:
		int h,s[N][N];
		void clear(){
			h=0;
			memset(s,0,sizeof(s));
		}
	public:
		Matrix operator + (Matrix x){
			Matrix y;
			y.clear();
			y.h=h;
			for(int i=0;i<h;i++)
				for(int j=0;j<h;j++)
					y.s[i][j]=(s[i][j]+x.s[i][j])%MOD;
			return y;
		}
		Matrix operator * (Matrix x){
			Matrix y;
			y.clear();
			y.h=h;
			for(int i=0;i<h;i++)
				for(int j=0;j<h;j++)
					for(int k=0;k<h;k++)
						y.s[i][j]=(y.s[i][j]+s[i][k]*x.s[k][j])%MOD;
			return y;
		}
		Matrix operator *= (Matrix x){
			return *this=*this*x;
		}
		void Init(int x){
			clear();
			h=x;
			for(int i=0;i<h;i++)
				for(int j=0;j<h;j++)
					scanf("%d",&s[i][j]);
		}
		void Enit(int x){
			clear();
			h=x;
			for(int i=0;i<x;i++)
				s[i][i]=1;
		}
		void Output(){
			for(int i=0;i<h;i++){
				for(int j=0;j<h;j++)
					printf("%d ",s[i][j]);
				puts("");
			}
		}
}A,E,ans;
Matrix Fp(int k){
	Matrix x,y;
	x.Enit(n);
	y=A;
	while(k){
		if(k&1)x*=y;
		k>>=1;
		y*=y;
	}
	return x;
}
void Dc(int k){
	if(k==1)ans=A;
	else{
		Dc(k/2);
		ans*=Fp(k/2)+E;
		ans=k&1?ans+Fp(k):ans;
	}
}
int main(){
	int k;scanf("%d%d%d",&n,&k,&MOD);
	A.Init(n),E.Enit(n);
	Dc(k);
	ans.Output();
	return 0;
}
posted @ 2018-09-13 23:56  Srzer  阅读(283)  评论(0编辑  收藏  举报