[关闭]
@wsndy-xx 2018-06-14T09:48:49.000000Z 字数 1027 阅读 887

Poj 3150 Cellular Automaton

题解


提交地址:https://vjudge.net/problem/POJ-3150

slove

次操作后的各格子写成矩阵 , 那么 的每一维都是 中的各

维的线性组合,可以利用矩阵乘法,设 , 当 时,有

最终答案 , 为初始矩阵,时间复杂度为 ,显然这样的

时间复杂度是无法承受的,观察矩阵 , 的一个特征是知道该矩阵的第一行就可以知

道该矩阵,这是一个循环矩阵,循环矩阵的矩阵乘法的时间复杂度为 ,这样的时

间复杂度是可以接受的。
这里做矩阵乘法时运用数组的 位置方便理解。

Code

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. const int N = 510;
  5. #define LL long long
  6. LL A[N], B[N], C[N], T[N];
  7. int n, M, d, k;
  8. void Mul(LL *a, LL *b, LL *c) {
  9. memset(T, 0, sizeof T);
  10. for(int i = 0; i < n; i ++)
  11. for(int j = 0; j < n; j ++) {
  12. if(i - j >= 0) T[i] = (T[i] + (a[j] * b[i - j]) % M) %
  13. M;
  14. else T[i] = (T[i] + (a[j] * b[i - j + n]) % M) % M;
  15. }
  16. for(int i = 0; i < n; i ++) c[i] = T[i];
  17. }
  18. void Ksm() {
  19. while(k) {
  20. if(k & 1) Mul(B, A, B); // B = B * A;
  21. Mul(A, A, A); // A = A * A;
  22. k >>= 1;
  23. }
  24. }
  25. int main() {
  26. std:: cin >> n >> M >> d >> k;
  27. for(int i = 0; i < n; i ++) std:: cin >> C[i];
  28. for(int i = 0; i <= d; i ++) A[i] = 1;
  29. for(int i = n - 1; i >= n - d; i --) A[i] = 1;
  30. B[0] = 1;
  31. Ksm();
  32. Mul(B, C, C);
  33. for(int i = 0; i < n; i ++) std:: cout << C[i] << " ";
  34. return 0;
  35. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注