您的位置:首页 > 其它

HDU 5015 233 Matrix(矩阵快速幂)

2016-03-02 09:17 218 查看
Description

一个(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,现输入a[1][0],…,a[m][0],求a
[m](mod 10000007)

Input

多组用例,每组用例第一行为两个整数n和m,之后为m个数表示a[1][0],…,a[m][0],以文件尾结束输入

Output

对于每组用例,输出a
[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)*(m+1)的矩阵A



所以对于任一个n,类似上例构造矩阵A,用矩阵快速幂加速求出A^m,然后再乘上矩阵B=[23,a[1][0],…,a[m][0],3],结果矩阵的第n+1个元素即为a
[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
[0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: