@wsndy-xx
2018-06-14T09:48:49.000000Z
字数 1027
阅读 864
题解
将 次操作后的各格子写成矩阵 , 那么 的每一维都是 中的各
维的线性组合,可以利用矩阵乘法,设 , 当 时,有
最终答案 , 为初始矩阵,时间复杂度为 ,显然这样的
时间复杂度是无法承受的,观察矩阵 , 的一个特征是知道该矩阵的第一行就可以知
道该矩阵,这是一个循环矩阵,循环矩阵的矩阵乘法的时间复杂度为 ,这样的时
间复杂度是可以接受的。
这里做矩阵乘法时运用数组的 位置方便理解。
#include <iostream>
#include <cstdio>
#include <cstring>
const int N = 510;
#define LL long long
LL A[N], B[N], C[N], T[N];
int n, M, d, k;
void Mul(LL *a, LL *b, LL *c) {
memset(T, 0, sizeof T);
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++) {
if(i - j >= 0) T[i] = (T[i] + (a[j] * b[i - j]) % M) %
M;
else T[i] = (T[i] + (a[j] * b[i - j + n]) % M) % M;
}
for(int i = 0; i < n; i ++) c[i] = T[i];
}
void Ksm() {
while(k) {
if(k & 1) Mul(B, A, B); // B = B * A;
Mul(A, A, A); // A = A * A;
k >>= 1;
}
}
int main() {
std:: cin >> n >> M >> d >> k;
for(int i = 0; i < n; i ++) std:: cin >> C[i];
for(int i = 0; i <= d; i ++) A[i] = 1;
for(int i = n - 1; i >= n - d; i --) A[i] = 1;
B[0] = 1;
Ksm();
Mul(B, C, C);
for(int i = 0; i < n; i ++) std:: cout << C[i] << " ";
return 0;
}