Problem p04024 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define mp make_pair
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(v) v.begin(), v.end()

const int maxn = 1e3 + 100;
const ll inf = 2e18, mod = 1e9 + 7;

int h, w;
ll k, ans, connect, blockcnt, rconnect, ANS, CONNECT, BLOCKCNT, RCONNECT;
char s[maxn][maxn], fixed_s[maxn][maxn];

ll powmod(ll a, ll b) {
  if (b == 1)
    return a;
  ll tmp = powmod(a, b / 2);
  tmp = tmp * tmp % mod;
  if (b & 1)
    tmp = tmp * a % mod;
  return tmp;
}

void handle() {
  ans = (ans * BLOCKCNT % mod - CONNECT * rconnect % mod + mod) % mod;
  connect = (connect * BLOCKCNT % mod + CONNECT * rconnect % mod) % mod;
  blockcnt = blockcnt * BLOCKCNT % mod;
  rconnect = rconnect * RCONNECT % mod;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  cin >> h >> w >> k;
  for (int i = 0; i < h; i++)
    cin >> s[i];

  ll cnt = 0;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      cnt += (s[i][j] == '#');

  bool hConnect = false, vConnect = false;
  for (int i = 0; i < h; i++)
    hConnect |= (s[i][0] == '#' && s[i][w - 1] == '#');
  for (int i = 0; i < w; i++)
    vConnect |= (s[0][i] == '#' && s[h - 1][i] == '#');
  if (hConnect && vConnect)
    cout << 1 << endl;
  else if (!hConnect && !vConnect)
    cout << powmod(cnt, k - 1) << endl;
  else {
    if (k <= 1) {
      cout << 1 << endl;
      return 0;
    }
    if (vConnect) {
      for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++)
          fixed_s[j][i] = s[i][j];
      swap(h, w);
    } else
      swap(s, fixed_s);

    ANS = ans = 1;
    BLOCKCNT = blockcnt = cnt;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w - 1; j++)
        CONNECT += (fixed_s[i][j] == '#' && fixed_s[i][j + 1] == '#');
    connect = CONNECT;
    for (int i = 0; i < h; i++)
      RCONNECT += (fixed_s[i][0] == '#' && fixed_s[i][w - 1] == '#');
    rconnect = RCONNECT;

    ans = BLOCKCNT - CONNECT;
    k -= 2;

    for (int bit = 0; bit < 63; bit++) {
      if ((k >> bit) & 1)
        handle();
      CONNECT = (CONNECT * BLOCKCNT % mod + CONNECT * RCONNECT % mod) % mod;
      BLOCKCNT = BLOCKCNT * BLOCKCNT % mod;
      RCONNECT = RCONNECT * RCONNECT % mod;
    }
    cout << ans << endl;
  }
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define mp make_pair
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(v) v.begin(), v.end()

const int maxn = 1e3 + 100;
const ll inf = 2e18, mod = 1e9 + 7;

int h, w;
ll k, ans, connect, blockcnt, rconnect, ANS, CONNECT, BLOCKCNT, RCONNECT;
char s[maxn][maxn], fixed_s[maxn][maxn];

ll powmod(ll a, ll b) {
  if (b == 1)
    return a;
  ll tmp = powmod(a, b / 2);
  tmp = tmp * tmp % mod;
  if (b & 1)
    tmp = tmp * a % mod;
  return tmp;
}

void handle() {
  ans = (ans * BLOCKCNT % mod - CONNECT * rconnect % mod + mod) % mod;
  connect = (connect * BLOCKCNT % mod + CONNECT * rconnect % mod) % mod;
  blockcnt = blockcnt * BLOCKCNT % mod;
  rconnect = rconnect * RCONNECT % mod;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  cin >> h >> w >> k;
  for (int i = 0; i < h; i++)
    cin >> s[i];

  ll cnt = 0;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      cnt += (s[i][j] == '#');

  bool hConnect = false, vConnect = false;
  for (int i = 0; i < h; i++)
    hConnect |= (s[i][0] == '#' && s[i][w - 1] == '#');
  for (int i = 0; i < w; i++)
    vConnect |= (s[0][i] == '#' && s[h - 1][i] == '#');
  if (hConnect && vConnect)
    cout << 1 << endl;
  else if (!hConnect && !vConnect) {
    if (k < 2)
      cout << 1 << endl;
    else
      cout << powmod(cnt, k - 1) << endl;
  } else {
    if (k <= 1) {
      cout << 1 << endl;
      return 0;
    }
    if (vConnect) {
      for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++)
          fixed_s[j][i] = s[i][j];
      swap(h, w);
    } else
      swap(s, fixed_s);

    ANS = ans = 1;
    BLOCKCNT = blockcnt = cnt;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w - 1; j++)
        CONNECT += (fixed_s[i][j] == '#' && fixed_s[i][j + 1] == '#');
    connect = CONNECT;
    for (int i = 0; i < h; i++)
      RCONNECT += (fixed_s[i][0] == '#' && fixed_s[i][w - 1] == '#');
    rconnect = RCONNECT;

    ans = BLOCKCNT - CONNECT;
    k -= 2;

    for (int bit = 0; bit < 63; bit++) {
      if ((k >> bit) & 1)
        handle();
      CONNECT = (CONNECT * BLOCKCNT % mod + CONNECT * RCONNECT % mod) % mod;
      BLOCKCNT = BLOCKCNT * BLOCKCNT % mod;
      RCONNECT = RCONNECT * RCONNECT % mod;
    }
    cout << ans << endl;
  }
}