HDU 5015 233 Matrix(矩阵快速幂)

52 篇文章 0 订阅

Description
一个 ( n + 1 ) × ( m + 1 ) (n+1)\times (m+1) (n+1)×(m+1)的矩阵a,a[0][0]=0,a[0][1]=233,a[0][2]=2333,…,a[i][j]=a[i-1][j]+a[i][j-1]](1<=i<=n,1<=j<=m),现输入a[1][0],…,a[m][0],求a[n][m](mod 10000007)
Input
多组用例,每组用例第一行为两个整数n和m,之后为m个数表示a[1][0],…,a[m][0],以文件尾结束输入
Output
对于每组用例,输出a[n][m](mod 10000007)
Sample Input
1 1
1
2 2
0 0
3 7
23 47 16
Sample Output
234
2799
72937
Solution
以n=3为例,构造辅助一个(n+2)*(n+2)的矩阵A
这里写图片描述
所以对于任一个n,类似上例构造矩阵A,用矩阵快速幂加速求出A^m,然后再乘上矩阵B=[23,a[1][0],…,a[m][0],3],结果矩阵的第n+1个元素即为a[n][m]
Code

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 15
typedef long long ll;
#define mod 10000007
struct Mat
{
	ll mat[maxn][maxn];//矩阵 
	int row,col;//矩阵行列数 
};
Mat mod_mul(Mat a,Mat b,int p)//矩阵乘法 
{
	Mat ans;
	ans.row=a.row;
	ans.col=b.col;
	memset(ans.mat,0,sizeof(ans.mat));
	for(int i=0;i<ans.row;i++)		
		for(int k=0;k<a.col;k++)
			if(a.mat[i][k])
				for(int j=0;j<ans.col;j++)
				{
					ans.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
					ans.mat[i][j]%=p;
				}
	return ans;
}
Mat mod_pow(Mat a,int k,int p)//矩阵快速幂 
{
	Mat ans;
	ans.row=a.row;
	ans.col=a.col;
	for(int i=0;i<a.row;i++)
		for(int j=0;j<a.col;j++)
			ans.mat[i][j]=(i==j);
	while(k)
	{
		if(k&1)ans=mod_mul(ans,a,p);
		a=mod_mul(a,a,p);
		k>>=1;
	}
	return ans;
}
int n,m;
int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		if(!n)
		{
			printf("0\n");
			continue;
		}
		Mat A,B;
		B.row=n+2,B.col=1;
		B.mat[0][0]=23ll,B.mat[n+1][0]=3ll;
		for(int i=1;i<=n;i++)scanf("%lld",&B.mat[i][0]);
		A.row=A.col=n+2;
		memset(A.mat,0,sizeof(A.mat));
		for(int i=0;i<n+1;i++)A.mat[i][0]=10ll;
		for(int i=0;i<n+2;i++)A.mat[i][n+1]=1ll;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=i;j++)
				A.mat[i][j]=1ll;
		A=mod_pow(A,m,mod);
		B=mod_mul(A,B,mod);
		printf("%lld\n",B.mat[n][0]);
	}
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值