poj 3233:Matrix Power Series

给定一个矩阵,求其前k次方的矩阵和。

 

二分+矩阵快速幂,S=(A1+A2+…+An)+(A1+A2+…+An)*k,然后递归求解A1+A2+…+An,递归结束条件k==1。

很早以前看的这题,当时不会,拖啊拖的,今天灵光乍现,不过A的也不顺利,递归一直写错,最后才AC。


#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

typedef struct D {
	int A[35][35];
}D;

D dd,kk;
int n,m;

D multi(D a,D b){
	D t;
	memset(t.A,0,sizeof(t.A));
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			for(int k=0;k<n;k++){
				t.A[i][j]+=a.A[i][k]*b.A[k][j];
				t.A[i][j]%=m;
			}
		}
	}
	return t;
}

D add(D a,D b){
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			a.A[i][j]+=b.A[i][j];
			a.A[i][j]%=m;
		}
	}
	return a;
}

D pow(int k){
	D p=dd,ans;
	memset(ans.A,0,sizeof(ans.A));
	for(int i=0;i<n;i++){
		ans.A[i][i]=1;
	}
	while(k>0){
		if(k&1){
			ans=multi(ans,p);
		}
		p=multi(p,p);
		k>>=1;
	}
	return ans;
}

D calcu(int k){
	if(k==1) return dd;

	D t=calcu(k>>1);
	if(k&1){
		D tt=pow((k>>1)+1);
		return add(add(t,tt),multi(t,tt));
	}
	else {
		D tt=pow(k>>1);
		return add(t,multi(t,tt));
	}
}

int main(){
	//freopen("in.txt","r",stdin);
	int k;
	cin>>n>>k>>m;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			cin>>dd.A[i][j];
			kk.A[i][j]=dd.A[i][j];
		}
	}
	D ss=calcu(k);
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			printf("%d%s",ss.A[i][j],(j+1>=n)?"\n":" ");
		}
	}
	
	return 0;
}



注:

不过题目的数据有点弱,有一个数据有明显的错误,这个代码还是AC了。此处注明,日后再解。

数据:

10 10000 100000

2 1 1 1 1 1 1 1 1 1

1 4 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 9 1 1 1 1

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值