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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章