Problem p01237 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 6;
const int MAX_W = 2 * MAX_N - 1;
const int MAX_H = 2 * MAX_N - 1;
const int MAX_GN = 3 * MAX_N * MAX_N - 3 * MAX_N + 1;

/* typedef */

typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> mtx;

/* global variables */

int n, l;
ll m;
int gn, h, wws[MAX_W];
int pmap[MAX_H][MAX_W];

/* subroutines */

void initmat(mtx &m0) {
  for (int i = 0; i < gn; i++)
    fill(m0[i].begin(), m0[i].end(), 0LL);
}

void mulmat(mtx &mm, const mtx &m0, const mtx &m1) {
  for (int i = 0; i < gn; i++)
    for (int j = 0; j < gn; j++) {
      ll &mij = mm[i][j];
      mij = 0;
      for (int k = 0; k < gn; k++)
        mij = (mij + m0[i][k] * m1[k][j]) % m;
    }
}

void mulmatvec(vl &vv, const mtx &mm, const vl &v0) {
  for (int i = 0; i < gn; i++) {
    vv[i] = 0;
    for (int j = 0; j < gn; j++)
      vv[i] = (vv[i] + mm[i][j] * v0[j]) % m;
  }
}

void powmat(mtx &mm, mtx m0, int e) {
  mtx m1(gn, vl(gn, 0LL));
  initmat(mm);
  for (int i = 0; i < gn; i++)
    mm[i][i] = 1LL;

  while (e > 0) {
    if (e & 1) {
      mulmat(m1, mm, m0);
      mm = m1;
    }

    mulmat(m1, m0, m0);
    m0 = m1;

    e >>= 1;
  }
}

void printmat(const mtx &mm) {
  for (int i = 0; i < gn; i++) {
    for (int j = 0; j < gn; j++)
      cout << mm[i][j] << ' ';
    cout << endl;
  }
}

/* main */

int main() {
  for (int cn = 1;; cn++) {
    cin >> n >> m >> l;
    if (n == 0)
      break;

    // gn = 2*sum_(i=n)^(n-2)i + 2n - 1 = 2(3n-2)(n-1)/2+2n-1
    // = 3n^2-3n-2n+2+2n-1 = 3n^2-3n+1

    gn = 3 * n * n - 3 * n + 1;

    vl vec(gn);
    for (int i = 0; i < gn; i++)
      cin >> vec[i];

    h = 2 * n - 1;

    for (int y = 0; y < n; y++)
      wws[y] = wws[h - 1 - y] = n + y;

    memset(pmap, -1, sizeof(pmap));
    int pos = 0;
    for (int y = 0; y < h; y++)
      for (int x = 0; x < wws[y]; x++)
        pmap[y][x] = pos++;

    mtx m0(gn, vl(gn, 0));

    for (int y = 0; y < n - 1; y++)
      for (int x = 0; x < wws[y]; x++) {
        int p0 = pmap[y][x];
        if (y > 0) {
          if (x - 1 >= 0)
            m0[p0][pmap[y - 1][x - 1]] = 1;
          if (x < wws[y - 1])
            m0[p0][pmap[y - 1][x]] = 1;
        }
        if (x - 1 >= 0)
          m0[p0][pmap[y][x - 1]] = 1;
        m0[p0][p0] = 1;
        if (x + 1 < wws[y])
          m0[p0][pmap[y][x + 1]] = 1;
        m0[p0][pmap[y + 1][x]] = 1;
        m0[p0][pmap[y + 1][x + 1]] = 1;
      }

    int y0 = n - 1;
    for (int x = 0; x < wws[y0]; x++) {
      int p0 = pmap[y0][x];
      if (y0 - 1 >= 0) {
        if (x - 1 >= 0)
          m0[p0][pmap[y0 - 1][x - 1]] = 1;
        if (x < wws[y0 - 1])
          m0[p0][pmap[y0 - 1][x]] = 1;
      }
      if (x - 1 >= 0)
        m0[p0][pmap[y0][x - 1]] = 1;
      m0[p0][p0] = 1;
      if (x + 1 < wws[y0])
        m0[p0][pmap[y0][x + 1]] = 1;
      if (y0 + 1 < h) {
        if (x - 1 >= 0)
          m0[p0][pmap[y0 + 1][x - 1]] = 1;
        if (x < wws[y0 + 1])
          m0[p0][pmap[y0 + 1][x]] = 1;
      }
    }

    for (int y = n; y < h; y++)
      for (int x = 0; x < wws[y]; x++) {
        int p0 = pmap[y][x];
        m0[p0][pmap[y - 1][x]] = 1;
        m0[p0][pmap[y - 1][x + 1]] = 1;
        if (x - 1 >= 0)
          m0[p0][pmap[y][x - 1]] = 1;
        m0[p0][p0] = 1;
        if (x + 1 < wws[y])
          m0[p0][pmap[y][x + 1]] = 1;
        if (y + 1 < h) {
          if (x - 1 >= 0)
            m0[p0][pmap[y + 1][x - 1]] = 1;
          if (x < wws[y + 1])
            m0[p0][pmap[y + 1][x]] = 1;
        }
      }
    // printmat(m0);

    mtx mm(gn, vl(gn));
    powmat(mm, m0, l);
    // printmat(mm);

    vl vv(gn);
    mulmatvec(vv, mm, vec);

    ll sum = 0;
    for (int i = 0; i < gn; i++)
      sum += vv[i];

    printf("Case %d: %lld\\n", cn, sum);
  }

  return 0;
}

Error: -6
free(): invalid next size (normal)


Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 6;
const int MAX_W = 2 * MAX_N - 1;
const int MAX_H = 2 * MAX_N - 1;
const int MAX_GN = 3 * MAX_N * MAX_N - 3 * MAX_N + 1;

/* typedef */

typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> mtx;

/* global variables */

int n, m, l;
int gn, h, wws[MAX_W];
int pmap[MAX_H][MAX_W];

/* subroutines */

void initmat(mtx &m0) {
  for (int i = 0; i < gn; i++)
    fill(m0[i].begin(), m0[i].end(), 0LL);
}

void mulmat(mtx &mm, const mtx &m0, const mtx &m1) {
  for (int i = 0; i < gn; i++)
    for (int j = 0; j < gn; j++) {
      ll &mij = mm[i][j];
      mij = 0;
      for (int k = 0; k < gn; k++)
        mij = (mij + m0[i][k] * m1[k][j]) % m;
    }
}

void mulmatvec(vl &vv, const mtx &mm, const vl &v0) {
  for (int i = 0; i < gn; i++) {
    vv[i] = 0;
    for (int j = 0; j < gn; j++)
      vv[i] = (vv[i] + mm[i][j] * v0[j]) % m;
  }
}

void powmat(mtx &mm, mtx m0, int e) {
  mtx m1(gn, vl(gn, 0LL));
  initmat(mm);
  for (int i = 0; i < gn; i++)
    mm[i][i] = 1LL;

  while (e > 0) {
    if (e & 1) {
      mulmat(m1, mm, m0);
      mm = m1;
    }

    mulmat(m1, m0, m0);
    m0 = m1;

    e >>= 1;
  }
}

void printmat(const mtx &mm) {
  for (int i = 0; i < gn; i++) {
    for (int j = 0; j < gn; j++)
      cout << mm[i][j] << ' ';
    cout << endl;
  }
}

/* main */

int main() {
  for (int cn = 1;; cn++) {
    cin >> n >> m >> l;
    if (n == 0)
      break;

    // gn = 2*sum_(i=n)^(n-2)i + 2n - 1 = 2(3n-2)(n-1)/2+2n-1
    // = 3n^2-3n-2n+2+2n-1 = 3n^2-3n+1

    gn = 3 * n * n - 3 * n + 1;

    vl vec(gn);
    for (int i = 0; i < gn; i++)
      cin >> vec[i];

    h = 2 * n - 1;

    for (int y = 0; y < n; y++)
      wws[y] = wws[h - 1 - y] = n + y;

    memset(pmap, -1, sizeof(pmap));
    int pos = 0;
    for (int y = 0; y < h; y++)
      for (int x = 0; x < wws[y]; x++)
        pmap[y][x] = pos++;

    mtx m0(gn, vl(gn, 0));

    for (int y = 0; y < n - 1; y++)
      for (int x = 0; x < wws[y]; x++) {
        int p0 = pmap[y][x];
        if (y > 0) {
          if (x - 1 >= 0)
            m0[p0][pmap[y - 1][x - 1]] = 1;
          if (x < wws[y - 1])
            m0[p0][pmap[y - 1][x]] = 1;
        }
        if (x - 1 >= 0)
          m0[p0][pmap[y][x - 1]] = 1;
        m0[p0][p0] = 1;
        if (x + 1 < wws[y])
          m0[p0][pmap[y][x + 1]] = 1;
        m0[p0][pmap[y + 1][x]] = 1;
        m0[p0][pmap[y + 1][x + 1]] = 1;
      }

    int y0 = n - 1;
    for (int x = 0; x < wws[y0]; x++) {
      int p0 = pmap[y0][x];
      if (y0 - 1 >= 0) {
        if (x - 1 >= 0)
          m0[p0][pmap[y0 - 1][x - 1]] = 1;
        if (x < wws[y0 - 1])
          m0[p0][pmap[y0 - 1][x]] = 1;
      }
      if (x - 1 >= 0)
        m0[p0][pmap[y0][x - 1]] = 1;
      m0[p0][p0] = 1;
      if (x + 1 < wws[y0])
        m0[p0][pmap[y0][x + 1]] = 1;
      if (y0 + 1 < h) {
        if (x - 1 >= 0)
          m0[p0][pmap[y0 + 1][x - 1]] = 1;
        if (x < wws[y0 + 1])
          m0[p0][pmap[y0 + 1][x]] = 1;
      }
    }

    for (int y = n; y < h; y++)
      for (int x = 0; x < wws[y]; x++) {
        int p0 = pmap[y][x];
        m0[p0][pmap[y - 1][x]] = 1;
        m0[p0][pmap[y - 1][x + 1]] = 1;
        if (x - 1 >= 0)
          m0[p0][pmap[y][x - 1]] = 1;
        m0[p0][p0] = 1;
        if (x + 1 < wws[y])
          m0[p0][pmap[y][x + 1]] = 1;
        if (y0 + 1 < h) {
          if (x - 1 >= 0)
            m0[p0][pmap[y + 1][x - 1]] = 1;
          if (x < wws[y + 1])
            m0[p0][pmap[y + 1][x]] = 1;
        }
      }
    // printmat(m0);

    mtx mm(gn, vl(gn));
    powmat(mm, m0, l);
    // printmat(mm);

    vl vv(gn);
    mulmatvec(vv, mm, vec);

    ll sum = 0;
    for (int i = 0; i < gn; i++)
      sum += vv[i];

    printf("Case %d: %lld\\n", cn, sum);
  }

  return 0;
}