poj 3150

矩阵乘法,运用循环矩阵性质。

代码:

#include<iostream>
#include<fstream>
#include<cmath>

using namespace std;
long long map[501][501],map1[501][501],map2[501][501];
long long m,d;
long long k;
long long a[501],b[501];
int n;
void solve(long long k){
	long long i,j;
	if(k==1)
	{
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				map1[i][j]=map[i][j];
	}
	else
	{
		solve(k/2);
		for(i=1;i<=n;i++)
		{
			map2[1][i]=0;
			for(j=1;j<=n;j++)
			{
				map2[1][i]+=map1[1][j]*map1[j][i];
				map2[1][i]%=m;
			}
		}
		for(i=2;i<=n;i++)
		{
			map2[i][1]=map2[i-1][n];
			for(j=2;j<=n;j++)
				map2[i][j]=map2[i-1][j-1];
		}
		if(k/2*2==k)
		{
			for(i=1;i<=n;i++)
				for(j=1;j<=n;j++)
					map1[i][j]=map2[i][j];
		}
		else
		{
			for(i=1;i<=n;i++)
			{
				map1[1][i]=0;
				for(j=1;j<=n;j++)
				{
					map1[1][i]+=map2[1][j]*map[j][i];
					map1[1][i]%=m;
				}
			}
			for(i=2;i<=n;i++)
			{
				map1[i][1]=map1[i-1][n];
				for(j=2;j<=n;j++)
					map1[i][j]=map1[i-1][j-1];
			}
		}
	}
}

		

void read(){
//	ifstream cin("in.txt");
	int i,j;
	while(cin>>n>>m>>d>>k)
	{
		for(i=1;i<=n;i++)
//			cin>>a[i];
		scanf("%lld",&a[i]);
		memset(map,0,sizeof(map));
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
				if(min(abs(i-j),n-abs(i-j))<=d)
					map[i][j]=1;
		}

		solve(k);
		for(i=1;i<=n;i++)
		{
			b[i]=0;
			for(j=1;j<=n;j++)
			{
				b[i]+=a[j]*map1[j][i];
				b[i]%=m;
			}
		}
		for(i=1;i<=n;i++)
			cout<<b[i]<<' ';
		cout<<endl;
	}
}

int main(){
	read();
	return 0;
}

posted on 2011-03-08 19:02  宇宙吾心  阅读(413)  评论(0)    收藏  举报

导航