题目链接:https://vjudge.net/problem/HDU-5015
233 Matrix
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2805 Accepted Submission(s): 1611
For each case, the first line contains two postive integers n,m(n ≤ 10,m ≤ 109). The second line contains n integers, a1,0,a2,0,...,an,0(0 ≤ ai,0 < 231).
1
2 2
0 0
3 7
23 47 16
2799
72937
题解:
假设n = 4,则矩阵中第0列元素为:
a[0][0]
a[1][0]
a[2][0]
a[3][0]
a[4][0]
根据递推,第1列为:
a[0][1] = a[0][1]
a[1][1] = a[0][1] + a[1][0]
a[2][1] = a[0][1] + a[1][0] + a[2][0]
a[3][1] = a[0][1] + a[1][0] + a[2][0] + a[3][0]
a[4][1] = a[0][1] + a[1][0] + a[2][0] + a[3][0] + a[4][0]
第m列为:
a[0][m] = a[0][m]
a[1][m] = a[0][m] + a[1][m-1]
a[2][m] = a[0][m] + a[1][m-1] + a[2][m-1]
a[3][m] = a[0][m] + a[1][m-1] + a[2][m-1] + a[3][m-1]
a[4][m] = a[0][m] + a[1][m-1] + a[2][m-1] + a[3][m-1]+ a[4][m-1]
可发现当前一列可直接由上一列递推出来,因此构造矩阵:
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = ;
const int MAXN = 1e6+; const int Size = ;
struct MA
{
LL mat[][];
void init()
{
for(int i = ; i<Size; i++)
for(int j = ; j<Size; j++)
mat[i][j] = (i==j);
}
}; MA mul(MA x, MA y)
{
MA ret;
memset(ret.mat, , sizeof(ret.mat));
for(int i = ; i<Size; i++)
for(int j = ; j<Size; j++)
for(int k = ; k<Size; k++)
ret.mat[i][j] += (1LL*x.mat[i][k]*y.mat[k][j])%MOD, ret.mat[i][j] %= MOD;
return ret;
} MA qpow(MA x, LL y)
{
MA s;
s.init();
while(y)
{
if(y&) s = mul(s, x);
x = mul(x, x);
y >>= ;
}
return s;
} int main()
{
LL n, m, a[];
while(scanf("%lld%lld",&n,&m)!=EOF)
{ for(int i = ; i<=n; i++)
scanf("%lld", &a[i]);
a[] = ; a[n+] = ; MA s;
memset(s.mat, , sizeof(s.mat));
for(int i = ; i<=n; i++)
{
s.mat[i][] = ;
s.mat[i][n+] = ;
for(int j = ; j<=i; j++)
s.mat[i][j] = ;
}
s.mat[n+][n+] = ; s = qpow(s, m);
LL ans = ;
for(int i = ; i<=n+; i++)
ans += 1LL*a[i]*s.mat[n][i]%MOD, ans %= MOD; printf("%lld\n", ans);
}
}