您的位置:首页 > 其它

POJ 3233

2015-10-10 11:11 369 查看
3233】 二分+矩阵

当n为偶数,Sn=(E+A^n/2)*Sn/2

当n为奇数,Sn=(E+A^n/2)*Sn/2+A^n

E为单位矩阵

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int n,k,m;
struct mat
{
	int a[35][35];
};
mat add(mat a,mat b)
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(b.a[i][j]) a.a[i][j]=(a.a[i][j]+b.a[i][j])%m;
		}
	}
	return a;
}
mat mul(mat a,mat b)
{
	mat ret;
	memset(ret.a,0,sizeof(ret.a));
	for(int i=0;i<n;i++)
	{
		for(int k=0;k<n;k++)
		{
			if(a.a[i][k])
			for(int j=0;j<n;j++)
			{
				if(b.a[k][j])
				ret.a[i][j]=(ret.a[i][j]+a.a[i][k]*b.a[k][j]%m)%m;
			}
		}
	}
	return ret;
}
mat mpower(mat a,int li)
{
	mat I;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			I.a[i][j]=(i==j);
		}
	}
	while(li)
	{
		if(li&1) I=mul(I,a);
		a=mul(a,a);
		li>>=1;
	}
	return I;
}
mat dfs(int li,mat A,mat I)
{
	if(li==1) return A;
	mat s=dfs(li>>1,A,I);
	s=mul(s,add(I,mpower(A,li/2)));
	if(li&1) s=add(s,mpower(A,li));
	return s;
}
int main()
{
	scanf("%d%d%d",&n,&k,&m);
	mat A,I;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			scanf("%d",&A.a[i][j]);
			A.a[i][j]%=m;
			I.a[i][j]=(i==j);
		}
	}
	mat tmp = dfs(k,A,I);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n-1;j++)
		{
			printf("%d ",tmp.a[i][j]);
		}
		printf("%d\n",tmp.a[i][n-1]);
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: