Problem p04024 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
#define all(x) (x).begin(), (x).end()

const int N = 500000;
const long long MOD = 1e9 + 7;

long long n, m, k;

string s[5000];

long long inq(long long a, long long b) {
  if (b == 0)
    return 1;
  long long l = inq(a, b / 2);
  if (b % 2)
    return l * l % MOD * a % MOD;
  return l * l % MOD;
}

struct Matrix {
  int n, m;
  long long a[50][50];
};

Matrix operator*(Matrix a, Matrix b) {
  Matrix c;
  c.n = a.n, c.m = b.m;
  for (int k = 0; k < a.m; k++) {
    for (int i = 0; i < a.n; i++) {
      for (int j = 0; j < b.m; j++) {
        c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j]) % MOD;
      }
    }
  }
  return c;
}

Matrix inq(Matrix a, long long b) {
  if (b == 0) {
    Matrix x;
    x.n = a.n, x.m = a.m;
    for (int i = 0; i < a.n; i++)
      x.a[i][i] = 1;
    return x;
  }
  Matrix l = inq(a, b / 2);
  if (b % 2)
    return l * l * a;
  return l * l;
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> k;
  for (int i = 0; i < n; i++)
    cin >> s[i];
  int c1 = 0, c2 = 0;
  for (int i = 0; i < n; i++) {
    if (s[i][0] == s[i][m - 1] && s[i][0] == '#')
      c1 = 1;
  }
  for (int j = 0; j < m; j++) {
    if (s[0][j] == s[n - 1][k] && s[0][j] == '#')
      c2 = 1;
  }
  if (!c1 && !c2) {
    long long cnt = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++)
        if (s[i][j] == '#')
          cnt++;
    }
    cout << inq(cnt, k - 1);
    return 0;
  }
  if (c1 && c2) {
    cout << 1;
    return 0;
  }
  if (c2 == 1) {
    string t[5000];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        t[j] += ".";
      }
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        t[j][i] = s[i][j];
      }
    }
    for (int i = 0; i < 5000; i++)
      s[i] = t[i];
    swap(n, m);
  }
  Matrix xy;
  xy.n = 2, xy.m = 1;
  xy.a[0][0] = 1, xy.a[1][0] = 1;
  Matrix dp;
  dp.n = 2, dp.m = 2;
  int a = 0, b = 0, c = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (s[i][j] == '#')
        a++;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j + 1 < m; j++) {
      if (s[i][j] == '#' && s[i][j + 1] == '#')
        b++;
    }
  }
  for (int i = 0; i < n; i++) {
    if (s[i][0] == '#' && s[i][m - 1] == '#')
      c++;
  }
  dp.a[0][0] = a, dp.a[0][1] = MOD - b, dp.a[1][1] = c;
  dp = inq(dp, k - 1);
  Matrix ans = dp * xy;
  cout << ans.a[0][0];
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
#define all(x) (x).begin(), (x).end()

const int N = 500000;
const long long MOD = 1e9 + 7;

long long n, m, k;

string s[5000];

long long inq(long long a, long long b) {
  if (b == 0)
    return 1;
  long long l = inq(a, b / 2);
  if (b % 2)
    return l * l % MOD * a % MOD;
  return l * l % MOD;
}

struct Matrix {
  int n, m;
  long long a[50][50];
};

Matrix operator*(Matrix a, Matrix b) {
  Matrix c;
  c.n = a.n, c.m = b.m;
  for (int k = 0; k < a.m; k++) {
    for (int i = 0; i < a.n; i++) {
      for (int j = 0; j < b.m; j++) {
        c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j]) % MOD;
      }
    }
  }
  return c;
}

Matrix inq(Matrix a, long long b) {
  if (b == 0) {
    Matrix x;
    x.n = a.n, x.m = a.m;
    for (int i = 0; i < a.n; i++)
      x.a[i][i] = 1;
    return x;
  }
  Matrix l = inq(a, b / 2);
  if (b % 2)
    return l * l * a;
  return l * l;
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> k;
  for (int i = 0; i < n; i++)
    cin >> s[i];
  int c1 = 0, c2 = 0;
  for (int i = 0; i < n; i++) {
    if (s[i][0] == s[i][m - 1] && s[i][0] == '#')
      c1 = 1;
  }
  for (int j = 0; j < m; j++) {
    if (s[0][j] == s[n - 1][j] && s[0][j] == '#')
      c2 = 1;
  }
  if (!c1 && !c2) {
    long long cnt = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++)
        if (s[i][j] == '#')
          cnt++;
    }
    cout << inq(cnt, k - 1);
    return 0;
  }
  if (c1 && c2) {
    cout << 1;
    return 0;
  }
  if (c2 == 1) {
    string t[5000];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        t[j] += ".";
      }
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        t[j][i] = s[i][j];
      }
    }
    for (int i = 0; i < 5000; i++)
      s[i] = t[i];
    swap(n, m);
  }
  Matrix xy;
  xy.n = 2, xy.m = 1;
  xy.a[0][0] = 1, xy.a[1][0] = 1;
  Matrix dp;
  dp.n = 2, dp.m = 2;
  int a = 0, b = 0, c = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (s[i][j] == '#')
        a++;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j + 1 < m; j++) {
      if (s[i][j] == '#' && s[i][j + 1] == '#')
        b++;
    }
  }
  for (int i = 0; i < n; i++) {
    if (s[i][0] == '#' && s[i][m - 1] == '#')
      c++;
  }
  dp.a[0][0] = a, dp.a[0][1] = MOD - b, dp.a[1][1] = c;
  dp = inq(dp, k - 1);
  Matrix ans = dp * xy;
  cout << ans.a[0][0];
}