# 玄学小记.2 ~ bzoj 4162: shlw loves matrix II

#include <bits/stdc++.h>
using namespace std;

// #define int long long
const int N = 55;
const int MOD = 1000000007;
char st[20000]; int k;
struct mat
{
int d[N][N];
mat()
{
memset(d, 0, sizeof d);
}
} X, P[N], I, ans;
mat operator * (mat a, mat b)
{
mat c;
for (int i = 0; i < k; ++ i)
for (int j = 0; j < k; ++ j)
for (int p = 0; p < k; ++ p)
c.d[i][j] = (1ll * a.d[i][p] * b.d[p][j] + c.d[i][j]) % MOD;
return c;
}
mat operator * (mat a, int b)
{
mat c;
for (int i = 0; i < k; ++ i)
for (int j = 0; j < k; ++ j)
c.d[i][j] = 1ll * a.d[i][j] * b % MOD;
return c;
}
mat operator + (mat a, mat b)
{
mat c;
for (int i = 0; i < k; ++ i)
for (int j = 0; j < k; ++ j)
c.d[i][j] = (a.d[i][j] + b.d[i][j]) % MOD;
return c;
}
int powi(int a, int b)
{
int c = 1;
for (; b; b /= 2, a = 1ll * a * a % MOD)
if (b & 1) c = 1ll * c * a % MOD;
return c;
}
int S[N], C[N];

struct poly
{
int d[N * 2];
poly ()
{
memset(d, 0, sizeof d);
}
} pI, pS;
poly operator * (poly a, poly b)
{
poly c;
for (int i = 0; i < k; ++ i)
for (int j = 0; j < k; ++ j)
c.d[i + j] = (c.d[i + j] + 1ll * a.d[i] * b.d[j]) % MOD;
for (int i = k + k - 2; i >= k; -- i)
{
int v = c.d[i];
for (int j = 0; j <= k; ++ j)
c.d[i - j] = (c.d[i - j] - 1ll * v * C[j] % MOD + MOD) % MOD;
}
return c;
}
poly powi(poly a, char b[], int l)
{
poly c = pI;
for (int i = l - 1; ~i; -- i, a = a * a)
if (b[i] == '1')
c = c * a;
return c;
}
signed main()
{
scanf("%s%d", st, &k);
int l = strlen(st);
for (int i = 0; i < k; ++ i) I.d[i][i] = 1;
pI.d[0] = 1;
for (int i = 0; i < k; ++ i)
for (int j = 0; j < k; ++ j)
scanf("%d", &X.d[i][j]);
P[0] = I; C[0] = 1;
for (int i = 1; i <= k; ++ i)
{
P[i] = P[i - 1] * X;
for (int j = 0; j < k; ++ j)
S[i] = (S[i] + P[i].d[j][j]) % MOD;
for (int j = 1; j <= i; ++ j)
C[i] = (C[i] - 1ll * C[j - 1] * S[i - j + 1] % MOD + MOD) % MOD;
C[i] = 1ll * C[i] * powi(i, MOD - 2) % MOD;
}
pS.d[1] = 1;
pS = powi(pS, st, l);

for (int i = 0; i < k; ++ i)
ans = ans + P[i] * pS.d[i];
for (int i = 0; i < k; ++ i)
{
for (int j = 0; j < k - 1; ++ j)
printf("%d ", ans.d[i][j]);
printf("%d", ans.d[i][k - 1]);
puts("");
}
}

posted @ 2017-06-22 17:58 AwD! 阅读(...) 评论(...) 编辑 收藏