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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
const double EPS = 1e-9;
const double PI = acos(-1.0);

const int MAX_HW = 1010;

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

int main() {

  vi p(1000000 + 1, 1);
  p[0] = p[1] = 0;
  FOR(i, 2, 1000 + 1) {
    if (p[i]) {
      for (int j = i * i; j <= 1000000; j += i) {
        p[j] = 0;
      }
    }
  }

  int m, n;
  while (cin >> m >> n, m) {
    pii start;

    int sty, stx;
    int top = INT_MAX, bottom = INT_MIN, left = INT_MAX, right = INT_MIN;
    vvi exist(MAX_HW, vi(MAX_HW));
    vvi canuse(MAX_HW, vi(MAX_HW));

    int y = MAX_HW / 2;
    int x = MAX_HW / 2;
    int move = 1, d = 0;
    int num = 1;
    int cnt = 1;
    while (1) {
      REP(_, move) {
        if (num == n) {
          sty = y;
          stx = x;
        }
        if (p[num]) {
          exist[y][x] = 1;
        }
        canuse[y][x] = num;
        y += dy[d];
        x += dx[d];
        if (num == m) {
          goto made;
        }
        num++;
        assert(y < MAX_HW && y >= 0 && x < MAX_HW && x >= 0);
      }
      d = (d + 1) % 4;
      if (cnt % 2 == 0) {
        move++;
      }
      cnt++;
    }
  made:;

    REP(i, MAX_HW) {
      REP(j, MAX_HW) {
        if (canuse[i][j]) {
          left = min(left, j);
          right = max(right, j);
          top = min(top, i);
          bottom = max(bottom, i);
        }
      }
    }

    vvi dp(MAX_HW, vi(MAX_HW));
    dp[sty][stx] = exist[sty][stx] + 1;
    vvi last(MAX_HW, vi(MAX_HW));
    if (exist[sty][stx]) {
      last[sty][stx] = canuse[sty][stx];
    } else {
      last[sty][stx] = -1;
    }

    FOR(i, sty + 1, bottom + 1) {
      FOR(j, left, right + 1) {
        if (!canuse[i][j]) {
          continue;
        }
        int saiyou = INT_MIN;
        int best = 0;
        for (int k = -1; k < 2; k++) {
          if (dp[i - 1][j + k] > best ||
              (saiyou != INT_MIN && dp[i - 1][j + k] == best &&
               last[i - 1][saiyou] < last[i - 1][j + k])) {
            assert(j + k >= left && j + k <= right);
            best = dp[i - 1][j + k];
            saiyou = j + k;
          }
        }

        if (saiyou != INT_MIN) {
          if (exist[i][j]) {
            dp[i][j] = best + 1;
            last[i][j] = canuse[i][j];
          } else {
            dp[i][j] = best;
            last[i][j] = last[i - 1][saiyou];
          }
        }
        // if(dp[i-1][j-1]>=1||dp[i-1][j]>=1||dp[i-1][j+1]>=1){
        //	dp[i][j] = max(dp[i-1][j-1], max(dp[i-1][j], dp[i-1][j+1])) +
        //exist[i][j];
        // }
        // if(exist[i][j]){
        //	last[i][j]=canuse[i][j];
        // }else{
        //	last[i][j]=max(last[i-1][j-1], max(last[i-1][j],
        //last[i-1][j+1]));
        // }
      }
    }

    int ans = -1, ansx, ansy;
    FOR(j, left, right + 1) {
      if (canuse[bottom][j]) {
        if (ans < dp[bottom][j]) {
          ans = dp[bottom][j];
          ansx = j;
          ansy = bottom;
        } else if (ans == dp[bottom][j] && last[bottom][j] > last[ansy][ansx]) {
          ansx = j;
          ansy = bottom;
        }
      } else if (canuse[bottom - 1][j]) {
        if (ans < dp[bottom - 1][j]) {
          ans = dp[bottom - 1][j];
          ansx = j;
          ansy = bottom - 1;
        } else if (ans == dp[bottom - 1][j] &&
                   last[bottom - 1][j] > last[ansy][ansx]) {
          ansx = j;
          ansy = bottom - 1;
        }
      }
    }

    // REP(i,MAX_HW){
    //	REP(j,MAX_HW){
    //		cerr<<dp[i][j];
    //	}
    //	cerr<<endl;
    // }

    if (ans - 1 == 0) {
      cout << "0 0" << endl;
    } else {
      cout << ans - 1 << " " << last[ansy][ansx] << endl;
    }
  }
}

Error: -11

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;

#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

const int MAX_HW = 1010;

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

int main() {

  vi p(1000000 + 1, 1);
  p[0] = p[1] = 0;
  FOR(i, 2, 1000 + 1) {
    if (p[i]) {
      for (int j = i * i; j <= 1000000; j += i) {
        p[j] = 0;
      }
    }
  }

  int m, n;
  while (cin >> m >> n, m) {
    pii start;

    int sty, stx;
    int top = INT_MAX, bottom = INT_MIN, left = INT_MAX, right = INT_MIN;
    vvi exist(MAX_HW, vi(MAX_HW));
    vvi canuse(MAX_HW, vi(MAX_HW));

    int y = MAX_HW / 2;
    int x = MAX_HW / 2;
    int move = 1, d = 0;
    int num = 1;
    int cnt = 1;
    while (1) {
      REP(_, move) {
        if (num == n) {
          sty = y;
          stx = x;
        }
        if (p[num]) {
          exist[y][x] = 1;
        }
        canuse[y][x] = num;
        y += dy[d];
        x += dx[d];
        if (num == m) {
          goto made;
        }
        num++;
        assert(y < MAX_HW && y >= 0 && x < MAX_HW && x >= 0);
      }
      d = (d + 1) % 4;
      if (cnt % 2 == 0) {
        move++;
      }
      cnt++;
    }
  made:;

    REP(i, MAX_HW) {
      REP(j, MAX_HW) {
        if (canuse[i][j]) {
          left = min(left, j);
          right = max(right, j);
          top = min(top, i);
          bottom = max(bottom, i);
        }
      }
    }

    vvi dp(MAX_HW, vi(MAX_HW));
    dp[sty][stx] = exist[sty][stx] + 1;
    vvi last(MAX_HW, vi(MAX_HW));
    if (exist[sty][stx]) {
      last[sty][stx] = canuse[sty][stx];
    } else {
      last[sty][stx] = -1;
    }

    FOR(i, sty + 1, bottom + 1) {
      FOR(j, left, right + 1) {
        if (!canuse[i][j]) {
          continue;
        }
        int saiyou = INT_MIN;
        int best = 0;
        for (int k = -1; k < 2; k++) {
          if (dp[i - 1][j + k] > best ||
              (dp[i - 1][j + k] == best &&
               last[i - 1][saiyou] < last[i - 1][j + k])) {
            assert(j + k >= left && j + k <= right);
            best = dp[i - 1][j + k];
            saiyou = j + k;
          }
        }

        if (saiyou != INT_MIN) {
          if (exist[i][j]) {
            dp[i][j] = best + 1;
            last[i][j] = canuse[i][j];
          } else {
            dp[i][j] = best;
            last[i][j] = last[i - 1][saiyou];
          }
        }
        // if(dp[i-1][j-1]>=1||dp[i-1][j]>=1||dp[i-1][j+1]>=1){
        //	dp[i][j] = max(dp[i-1][j-1], max(dp[i-1][j], dp[i-1][j+1])) +
        //exist[i][j];
        // }
        // if(exist[i][j]){
        //	last[i][j]=canuse[i][j];
        // }else{
        //	last[i][j]=max(last[i-1][j-1], max(last[i-1][j],
        //last[i-1][j+1]));
        // }
      }
    }

    int ans = -1, ansx, ansy;
    FOR(j, left, right + 1) {
      if (canuse[bottom][j]) {
        if (ans < dp[bottom][j]) {
          ans = dp[bottom][j];
          ansx = j;
          ansy = bottom;
        } else if (ans == dp[bottom][j] && last[bottom][j] > last[ansy][ansx]) {
          ansx = j;
          ansy = bottom;
        }
      } else if (canuse[bottom - 1][j]) {
        if (ans < dp[bottom - 1][j]) {
          ans = dp[bottom - 1][j];
          ansx = j;
          ansy = bottom - 1;
        } else if (ans == dp[bottom - 1][j] &&
                   last[bottom - 1][j] > last[ansy][ansx]) {
          ansx = j;
          ansy = bottom - 1;
        }
      }
    }

    // REP(i,MAX_HW){
    //	REP(j,MAX_HW){
    //		cerr<<dp[i][j];
    //	}
    //	cerr<<endl;
    // }

    if (ans - 1 == 0) {
      cout << "0 0" << endl;
    } else {
      cout << ans - 1 << " " << last[ansy][ansx] << endl;
    }
  }
}