Problem p03088 (C++)

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

using namespace std;

bool is_allowed(vector<int> vs) {
  assert(vs.size() == 4);
  auto check = [&]() {
    if (vs[0] == 0 && vs[1] == 1 && vs[2] == 2) {
      return false;
    }
    if (vs[1] == 0 && vs[2] == 1 && vs[3] == 2) {
      return false;
    }
    return true;
  };
  if (!check()) {
    return false;
  }
  for (int i = 0; i < 3; ++i) {
    swap(vs[i], vs[i + 1]);
    if (!check()) {
      return false;
    }
    swap(vs[i], vs[i + 1]);
  }
  return true;
}

vector<vector<int>> all_allowed() {
  vector<vector<int>> all;
  for (int a = 0; a < 4; ++a) {
    for (int b = 0; b < 4; ++b) {
      for (int c = 0; c < 4; ++c) {
        for (int d = 0; d < 4; ++d) {
          vector<int> xs = {a, b, c, d};
          if (is_allowed(xs)) {
            all.push_back(xs);
          }
        }
      }
    }
  }
  return all;
}

long long prime = 1000000007;

vector<vector<long long>> mul(vector<vector<long long>> a,
                              vector<vector<long long>> b) {
  // auto t0 = clock();
  // assert (a[0].size() == b.size());
  int m = (int)a.size(), n = (int)b.size(), p = (int)b[0].size();
  // (m x n) * (n x p)
  vector<vector<long long>> c(m, vector<long long>(p, 0LL));
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < p; ++j) {
      long long s = 0;
      for (int k = 0; k < n; ++k) {
        s += (a[i][k] * b[k][j]) % prime;
      }
      c[i][j] = s % prime;
    }
  }
  // cerr << "simple mul time: " << (clock() - t0) << " -- " << m << ", " << n
  // << ", " << p << endl;
  return c;
}

vector<vector<long long>> pow(vector<vector<long long>> a, int r) {
  if (r == 1) {
    return a;
  }
  if (r % 2 == 1) {
    auto b = pow(a, r - 1);
    return mul(a, b);
  }
  auto b = pow(a, r / 2);
  return mul(b, b);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<long long> answers = {
      0,         0,         0,         61,        230,       865,
      3247,      12185,     45719,     171531,    643550,    2414454,
      9058467,   33985227,  127504505, 478366600, 794717734, 733354121,
      261943303, 776803305, 580025381, 51688048,  44657419,  737209731,
      604119499, 159693437, 858533109, 639056669, 549054109, 996291083,
      531294469, 23314687,  783022045, 855462856, 649970414, 68697295,
      409213624, 604356692, 88638656,  978442997, 534833116, 763737161,
      785892908, 123883652, 639213333, 181836645, 998121103, 124885216,
      501575626, 39816123,  113468411, 799008836, 775465589, 256852905,
      664630886, 971550783, 751629411, 51018086,  702530485, 725438992,
      696683714, 792638194, 221791721, 149602322, 414054379, 986519078,
      981760191, 305799096, 515140586, 406959393, 975058685, 245601370,
      324759692, 673385295, 191483611, 570246669, 427196161, 781042769,
      569725155, 842176273, 25328739,  847501730, 206282374, 353770801,
      323137024, 371653459, 940737264, 123820509, 915711339, 847205021,
      252858375, 718889563, 866398347, 738390145, 133009077, 333099663,
      170591295, 329869205, 616680192, 597534442, 388130742};

  if (n == 3) {
    cout << 61 << endl;
    return 0;
  }
  map<vector<int>, int> mapping;
  for (auto &xs : all_allowed()) {
    mapping[xs] = (int)mapping.size();
    assert(mapping[xs] < 230);
  }
  if (n <= 98) {
    cout << answers[n] << endl;
    return 0;
  }
  vector<vector<long long>> mat(mapping.size(),
                                vector<long long>(mapping.size(), 0));
  for (auto &ys : all_allowed()) {
    for (int a = 0; a < 4; ++a) {
      vector<int> xs(ys.begin() + 1, ys.end());
      xs.push_back(a);
      if (is_allowed(xs)) {
        ++mat[mapping[ys]][mapping[xs]];
      }
    }
  }
  vector<vector<long long>> u(mapping.size(), vector<long long>(1, 1LL));
  // auto t0 = clock();
  vector<vector<long long>> v = u;

  // vector<long long> answers = {0, 0, 0, 61, 230};
  // for (int i = 5; i <= 100; ++i) {
  // v = mul(mat, v);
  // long long tmp = 0;
  // for (auto& p : v) {
  // tmp += p[0];
  // }
  // answers.push_back(tmp % prime);
  // }
  // cerr << "{";
  // for (auto answer : answers) {
  // cout << answer << ", ";
  // }
  // cerr << "}" << endl;
  if (n > 4) {
    auto x = pow(mat, n - 4);
    v = mul(x, u);
  }
  // cerr << "pow time = " << (clock() - t0) << endl;
  // assert (v[0].size() == 1);
  long long result = 0;
  for (auto &p : v) {
    result += p[0];
  }
  cout << (result % prime) << endl;
  return 0;
}


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

using namespace std;

bool is_allowed(vector<int> vs) {
  assert(vs.size() == 4);
  auto check = [&]() {
    if (vs[0] == 0 && vs[1] == 1 && vs[2] == 2) {
      return false;
    }
    if (vs[1] == 0 && vs[2] == 1 && vs[3] == 2) {
      return false;
    }
    return true;
  };
  if (!check()) {
    return false;
  }
  for (int i = 0; i < 3; ++i) {
    swap(vs[i], vs[i + 1]);
    if (!check()) {
      return false;
    }
    swap(vs[i], vs[i + 1]);
  }
  return true;
}

vector<vector<int>> all_allowed() {
  vector<vector<int>> all;
  for (int a = 0; a < 4; ++a) {
    for (int b = 0; b < 4; ++b) {
      for (int c = 0; c < 4; ++c) {
        for (int d = 0; d < 4; ++d) {
          vector<int> xs = {a, b, c, d};
          if (is_allowed(xs)) {
            all.push_back(xs);
          }
        }
      }
    }
  }
  return all;
}

long long prime = 1000000007;

vector<vector<long long>> mul(vector<vector<long long>> a,
                              vector<vector<long long>> b) {
  // auto t0 = clock();
  // assert (a[0].size() == b.size());
  int m = (int)a.size(), n = (int)b.size(), p = (int)b[0].size();
  // (m x n) * (n x p)
  vector<vector<long long>> c(m, vector<long long>(p, 0LL));
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < p; ++j) {
      long long s = 0;
      for (int k = 0; k < n; ++k) {
        s += (a[i][k] * b[k][j]) % prime;
      }
      c[i][j] = s % prime;
    }
  }
  // cerr << "simple mul time: " << (clock() - t0) << " -- " << m << ", " << n
  // << ", " << p << endl;
  return c;
}

vector<vector<long long>> pow(vector<vector<long long>> a, int r) {
  if (r == 1) {
    return a;
  }
  if (r % 2 == 1) {
    auto b = pow(a, r - 1);
    return mul(a, b);
  }
  auto b = pow(a, r / 2);
  return mul(b, b);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<long long> answers = {
      0,         0,         0,         61,        230,       865,
      3247,      12185,     45719,     171531,    643550,    2414454,
      9058467,   33985227,  127504505, 478366600, 794717734, 733354121,
      261943303, 776803305, 580025381, 51688048,  44657419,  737209731,
      604119499, 159693437, 858533109, 639056669, 549054109, 996291083,
      531294469, 23314687,  783022045, 855462856, 649970414, 68697295,
      409213624, 604356692, 88638656,  978442997, 534833116, 763737161,
      785892908, 123883652, 639213333, 181836645, 998121103, 124885216,
      501575626, 39816123,  113468411, 799008836, 775465589, 256852905,
      664630886, 971550783, 751629411, 51018086,  702530485, 725438992,
      696683714, 792638194, 221791721, 149602322, 414054379, 986519078,
      981760191, 305799096, 515140586, 406959393, 975058685, 245601370,
      324759692, 673385295, 191483611, 570246669, 427196161, 781042769,
      569725155, 842176273, 25328739,  847501730, 206282374, 353770801,
      323137024, 371653459, 940737264, 123820509, 915711339, 847205021,
      252858375, 718889563, 866398347, 738390145, 133009077, 333099663,
      170591295, 329869205, 616680192, 597534442, 388130742};

  if (n == 3) {
    cout << 61 << endl;
    return 0;
  }
  map<vector<int>, int> mapping;
  for (auto &xs : all_allowed()) {
    int t = (int)mapping.size();
    mapping[xs] = t;
    assert(mapping[xs] < 230);
  }
  if (n <= 98) {
    cout << answers[n] << endl;
    return 0;
  }
  vector<vector<long long>> mat(mapping.size(),
                                vector<long long>(mapping.size(), 0));
  for (auto &ys : all_allowed()) {
    for (int a = 0; a < 4; ++a) {
      vector<int> xs(ys.begin() + 1, ys.end());
      xs.push_back(a);
      if (is_allowed(xs)) {
        ++mat[mapping[ys]][mapping[xs]];
      }
    }
  }
  vector<vector<long long>> u(mapping.size(), vector<long long>(1, 1LL));
  // auto t0 = clock();
  vector<vector<long long>> v = u;

  // vector<long long> answers = {0, 0, 0, 61, 230};
  // for (int i = 5; i <= 100; ++i) {
  // v = mul(mat, v);
  // long long tmp = 0;
  // for (auto& p : v) {
  // tmp += p[0];
  // }
  // answers.push_back(tmp % prime);
  // }
  // cerr << "{";
  // for (auto answer : answers) {
  // cout << answer << ", ";
  // }
  // cerr << "}" << endl;
  if (n > 4) {
    auto x = pow(mat, n - 4);
    v = mul(x, u);
  }
  // cerr << "pow time = " << (clock() - t0) << endl;
  // assert (v[0].size() == 1);
  long long result = 0;
  for (auto &p : v) {
    result += p[0];
  }
  cout << (result % prime) << endl;
  return 0;
}