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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};

#define mp make_pair
typedef pair<int, int> pii;

const int M_MAX = 1000010;
const int N = 4000;

// 4000*4000*4 = 16000000*4 = 16MB*4=64MB
// 1MB
pii fill(vector<vector<int>> &maze, int x, int y, int dir, int k, int s) {
  for (int i = 0; i < k; i++) {
    maze[y + i * dy[dir]][x + i * dx[dir]] = s++;
  }
  return mp(x + k * dx[dir], y + k * dy[dir]);
}

void make(vector<vector<int>> &maze) {
  pii now = mp(N / 2, N / 2);
  int k = 1;
  int num = 1;
  while (num <= M_MAX) {
    now = fill(maze, now.first, now.second, 0, k, num);
    num += k;
    now = fill(maze, now.first, now.second, 1, k, num);
    num += k;
    k++;
    now = fill(maze, now.first, now.second, 2, k, num);
    num += k;
    now = fill(maze, now.first, now.second, 3, k, num);
    num += k;
    k++;
  }
}

char isprime[M_MAX];

void era() {
  for (int i = 0; i < M_MAX; i++) {
    isprime[i] = 1;
  }
  isprime[0] = isprime[1] = 0;
  for (int i = 2; i < M_MAX; i++) {
    if (isprime[i]) {
      for (int j = i + i; j < M_MAX; j += i) {
        isprime[j] = 0;
      }
    }
  }
}

void solve(vector<vector<int>> &maze, int m, int n) {
  int sx, sy;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (maze[i][j] == n) {
        sx = j, sy = i;
      }
    }
  }
  vector<vector<int16_t>> dp(N, vector<int16_t>(N, -1));
  dp[sy][sx] = isprime[maze[sy][sx]];
  for (int i = 0; i < N - 1; i++) {
    for (int j = 0; j < N; j++) {
      if (maze[i][j] > m)
        continue;
      if (dp[i][j] == -1)
        continue;
      if (j >= 1)
        dp[i + 1][j - 1] =
            max(dp[i + 1][j - 1],
                (int16_t)(dp[i][j] + isprime[maze[i + 1][j - 1]]));
      dp[i + 1][j] =
          max(dp[i + 1][j], (int16_t)(dp[i][j] + isprime[maze[i + 1][j]]));
      if (j < N - 1)
        dp[i + 1][j + 1] =
            max(dp[i + 1][j + 1],
                (int16_t)(dp[i][j] + isprime[maze[i + 1][j + 1]]));
    }
  }
  int ma = 0;
  int ma_ind = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (maze[i][j] > m)
        continue;
      if (ma <= dp[i][j] && isprime[maze[i][j]]) {
        if (ma < dp[i][j]) {
          ma = dp[i][j];
          ma_ind = maze[i][j];
        } else {
          if (ma_ind < maze[i][j])
            ma_ind = maze[i][j];
        }
      }
    }
  }
  if (ma == 0) {
    cout << "0 0" << endl;
  } else {
    cout << ma << " " << ma_ind << endl;
  }
}

int main() {
  vector<vector<int>> maze(N, vector<int>(N, 0));
  make(maze);
  era();

  int n, m;
  while (cin >> m >> n, m != 0) {
    solve(maze, m, n);
  }

  return 0;
}


Error: -6
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};

#define mp make_pair
typedef pair<int, int> pii;

pii fill(vector<vector<int>> &maze, int x, int y, int dir, int k, int s) {
  for (int i = 0; i < k; i++) {
    maze[y + i * dy[dir]][x + i * dx[dir]] = s++;
  }
  return mp(x + k * dx[dir], y + k * dy[dir]);
}

void make(vector<vector<int>> &maze) {
  pii now = mp(2000, 2000);
  int k = 1;
  int num = 1;
  while (num <= 1000000) {
    now = fill(maze, now.first, now.second, 0, k, num);
    num += k;
    now = fill(maze, now.first, now.second, 1, k, num);
    num += k;
    k++;
    now = fill(maze, now.first, now.second, 2, k, num);
    num += k;
    now = fill(maze, now.first, now.second, 3, k, num);
    num += k;
    k++;
  }
}

int isprime[1000010];

void era() {
  for (int i = 0; i < 1000010; i++) {
    isprime[i] = 1;
  }
  isprime[0] = isprime[1] = 0;
  for (int i = 2; i < 1000010; i++) {
    if (isprime[i]) {
      for (int j = i + i; j < 1000010; j += i) {
        isprime[j] = 0;
      }
    }
  }
}

void solve(vector<vector<int>> &maze, int m, int n) {
  int sx, sy;
  for (int i = 0; i < 4000; i++) {
    for (int j = 0; j < 4000; j++) {
      if (maze[i][j] == n) {
        sx = j, sy = i;
      }
    }
  }
  vector<vector<int>> dp(4000, vector<int>(4000, -1));
  dp[sy][sx] = isprime[maze[sy][sx]];
  for (int i = 0; i < 3999; i++) {
    for (int j = 0; j < 4000; j++) {
      if (maze[i][j] > m)
        continue;
      if (dp[i][j] == -1)
        continue;
      if (j >= 1)
        dp[i + 1][j - 1] =
            max(dp[i + 1][j - 1], dp[i][j] + isprime[maze[i + 1][j - 1]]);
      dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + isprime[maze[i + 1][j]]);
      if (j < 3999)
        dp[i + 1][j + 1] =
            max(dp[i + 1][j + 1], dp[i][j] + isprime[maze[i + 1][j + 1]]);
    }
  }

  int ma = 0;
  int ma_ind = 0;
  for (int i = 0; i < 4000; i++) {
    for (int j = 0; j < 4000; j++) {
      if (maze[i][j] > m)
        continue;
      if (ma <= dp[i][j] && isprime[maze[i][j]]) {
        if (ma < dp[i][j]) {
          ma = dp[i][j];
          ma_ind = maze[i][j];
        } else {
          if (ma_ind < maze[i][j])
            ma_ind = maze[i][j];
        }
      }
    }
  }
  if (ma == 0) {
    cout << "0 0" << endl;
  } else {
    cout << ma << " " << ma_ind << endl;
  }
}

int main() {
  vector<vector<int>> maze(4000, vector<int>(4000, 0));
  make(maze);
  era();

  int n, m;
  while (cin >> m >> n, m != 0) {
    solve(maze, m, n);
  }

  return 0;
}