POJ 3233 Matrix Power Series

POJ 3233 Matrix Power Series

题目链接:http://poj.org/problem?id=3233


运用两次二分,对Ak运用快速幂,对S用二分处理(求一个递归式)


题意:求 S=A+A2+A3+ … +Ak.

思路:AK首先想到矩阵快速幂。

1.当K为奇数时,如K=5时 sum(5)=A+A^2+A^3+A^4+A^5=A+A^2+A^3*(A+A^2)+A^3=sum(2)+A^3*sum(2)+A^3=sum(5/2)+A^(5/2+1)*sum(5/2)+A^(5/2+1)

 所以sum(n)=sum(n/2)+A^(n/2+1)*sum(n/2)+A^(n/2+1)

2.当K为偶数时,如K=4时 sum(4)=A+A^2+A^3+A^4=A^2*(A+A^2)+A+A^2=A^2*sum(2)+sum(2)=A^(4/2)*sum(4/2)+sum(4/2);

 所以sum(n)=A^(n/2)*sum(n/2)+sum(n/2);



#include<stdio.h>
#include<string.h>

struct Matrix
{
	int m[40][40];
};
struct Matrix I,s;
int n,kmod;

Matrix Mul(Matrix a,Matrix b)
{
	Matrix c;
	int i,j,k;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			c.m[i][j]=0;
			for(k=0;k<n;k++)
			{
				c.m[i][j]+=(a.m[i][k]*b.m[k][j]);
				c.m[i][j]%=kmod;
			}
		}
	}
	return c;
}

Matrix Add(Matrix a,Matrix b)
{
	Matrix c;
	int i,j;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			c.m[i][j]=(a.m[i][j]+b.m[i][j]);
			c.m[i][j]%=kmod;
		}
	}
	return c;
}

Matrix Quickpow(Matrix a,int n)
{
	Matrix m,b;
	m=a,b=I;
	while(n)
	{
		if(n%2)
			b=Mul(b,m);
		n/=2;
		m=Mul(m,m);
	}
	return b;
}

Matrix Sum(int n)
{
	Matrix ans,temp;
	if(n==1)
		return s;
	temp=Sum(n/2);
	if(n%2) //n为奇数时sum(n)=sum(n/2)+sum(n/2)*s^(n/2+1)+s^(n/2+1)
	{	
		ans=Quickpow(s,(n/2)+1);
		temp=Add(temp,Mul(temp,ans));
		ans=Add(ans,temp);

	}
	else //n为偶数时sum(n)=sum(n/2)+sum(n/2)*s^(n/2)
	{
		ans=Quickpow(s,n/2);
		ans=Add(temp,Mul(ans,temp));
	}
	return ans;
}

int main()
{
	int i,j;
	int k;
	while(scanf("%d %d %d",&n,&k,&kmod)!=EOF)
	{
		memset(I.m,0,sizeof I.m);
		for(i=0;i<n;i++)
			I.m[i][i]=1;
		for(i=0;i<n;i++)
		{
			for(j=0;j<n;j++)
			{
				scanf("%d",&s.m[i][j]);
			}
		}
		Matrix ans;
		ans=Sum(k);
		for(i=0;i<n;i++)
		{
			for(j=0;j<n-1;j++)
			{
				printf("%d ",ans.m[i][j]);
			}
			printf("%d\n",ans.m[i][j]);
		}
	}

return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值