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

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>

using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 1000010;
int _w;

int a, b, c, d;

void bmax(int &a, int b) { a = b > a ? b : a; }
void bmin(int &a, int b) { a = b < a ? b : a; }
int calc(int x1, int x2, int y1, int y2, int z1, int z2) {
  if (x1 > a - 1 || y1 > b - 1 || z1 > c - 1 || x2 < 0 || y2 < 0 || z2 < 0)
    return 0;
  bmax(x1, 0), bmin(x1, a - 1), bmax(x2, 0), bmin(x2, a - 1);
  bmax(y1, 0), bmin(y1, b - 1), bmax(y2, 0), bmin(y2, b - 1);
  bmax(z1, 0), bmin(z1, c - 1), bmax(z2, 0), bmin(z2, c - 1);
  int x = x2 - x1 + 1, y = y2 - y1 + 1, z = z2 - z1 + 1;
  return int((ll)x * y % MOD * z % MOD);
}
int calc2(int x, int y, int z, int xx, int yy, int zz) {
  if (xx != x) {
    return calc(x + d, x + d, y - d, y + d, z - d, z + d);
  } else if (yy != y) {
    return calc(x - d, x + d, y + d, y + d, z - d, z + d);
  } else if (zz != z) {
    return calc(x - d, x + d, y - d, y + d, z + d, z + d);
  }
  assert(0);
}

void nextblock(int x, int y, int z, int &xx, int &yy, int &zz) {
  xx = x + 1;
  yy = int((ll)xx * b / a);
  zz = int((ll)xx * c / a);
  if (yy == y && zz == z)
    return;
  yy = y + 1;
  xx = int((ll)yy * a / b);
  zz = int((ll)yy * c / b);
  if (xx == x && zz == z)
    return;
  zz = z + 1;
  xx = int((ll)zz * a / c);
  yy = int((ll)zz * b / c);
  if (xx == x && yy == y)
    return;
  printf("nextblock(%d, %d, %d)\\n", x, y, z);
  assert(0);
}

bool test(int x, int y, int z, int xx, int yy, int zz) {
  if (xx < x || yy < y || zz < z)
    return false;
  if ((x < d && xx != x) || (y < d && yy != y) || (z < d && zz != z) ||
      (xx >= a - 1 - d && xx != x) || (yy >= b - 1 - d && yy != y) ||
      (zz >= c - 1 - d && zz != z))
    return false;
  else
    return true;
}

void jumpx(int x, int y, int z, int &xx, int &yy, int &zz) {
  int low = x, high = a - 1;
  while (low < high) {
    int mid = (low + high + 1) >> 1;
    int tx = mid;
    int ty = int((ll)tx * b / a);
    int tz = int((ll)tx * c / a);
    if (test(x, y, z, tx, ty, tz))
      low = mid;
    else
      high = mid - 1;
  }
  int tx = low;
  int ty = int((ll)tx * b / a);
  int tz = int((ll)tx * c / a);
  bmax(xx, tx), bmax(yy, ty), bmax(zz, tz);
}

void jumpy(int x, int y, int z, int &xx, int &yy, int &zz) {
  int low = y, high = b - 1;
  while (low < high) {
    int mid = (low + high + 1) >> 1;
    int ty = mid;
    int tx = int((ll)ty * a / b);
    int tz = int((ll)ty * c / b);
    if (test(x, y, z, tx, ty, tz))
      low = mid;
    else
      high = mid - 1;
  }
  int ty = low;
  int tx = int((ll)ty * a / b);
  int tz = int((ll)ty * c / b);
  bmax(xx, tx), bmax(yy, ty), bmax(zz, tz);
}

void jumpz(int x, int y, int z, int &xx, int &yy, int &zz) {
  int low = z, high = c - 1;
  while (low < high) {
    int mid = (low + high + 1) >> 1;
    int tz = mid;
    int ty = int((ll)tz * b / c);
    int tx = int((ll)tz * a / c);
    if (test(x, y, z, tx, ty, tz))
      low = mid;
    else
      high = mid - 1;
  }
  int tz = low;
  int ty = int((ll)tz * b / c);
  int tx = int((ll)tz * a / c);
  bmax(xx, tx), bmax(yy, ty), bmax(zz, tz);
}

void jumpnext(int x, int y, int z, int &xx, int &yy, int &zz) {
  xx = x, yy = y, zz = z;
  jumpx(x, y, z, xx, yy, zz);
  jumpy(x, y, z, xx, yy, zz);
  jumpz(x, y, z, xx, yy, zz);
}

int x[MAXN], y[MAXN], z[MAXN], v[MAXN], v2[MAXN], sz;
bool checkend() {
  return x[sz - 1] == a - 1 && y[sz - 1] == b - 1 && z[sz - 1] == c - 1;
}
void solve() {
  x[sz] = y[sz] = z[sz] = 0;
  v[sz++] = calc(-d, d, -d, d, -d, d);
  while (!checkend()) {
    int xx, yy, zz;
    nextblock(x[sz - 1], y[sz - 1], z[sz - 1], xx, yy, zz);
    v2[sz - 1] = calc2(xx, yy, zz, x[sz - 1], y[sz - 1], z[sz - 1]);
    jumpnext(x[sz - 1], y[sz - 1], z[sz - 1], x[sz], y[sz], z[sz]);
    xx = x[sz], yy = y[sz], zz = z[sz];
    // printf( "x = %d, y = %d, z = %d, (pre)\\n", xx, yy, zz );
    nextblock(xx, yy, zz, x[sz], y[sz], z[sz]);
    v[sz] = calc2(x[sz], y[sz], z[sz], xx, yy, zz);
    // printf( "x = %d, y = %d, z = %d, sz = %d\\n", x[sz], y[sz], z[sz], sz );
    ++sz;
  }
  int ans = 0;
  for (int i = 1; i < sz; ++i) {
    ll cnt = (ll)x[i] - x[i - 1] + y[i] - y[i - 1] + z[i] - z[i - 1];
    ans = int((ans + v[i - 1] + (cnt - 1) % MOD * v2[i - 1]) % MOD);
  }
  printf("%d\\n", (ans + (d == 0)) % MOD);
}

int main() {
  _w = scanf("%d%d%d%d", &a, &b, &c, &d);
  solve();
  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>

using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 1000010;
int _w;

int a, b, c, d;

void bmax(int &a, int b) { a = b > a ? b : a; }
void bmin(int &a, int b) { a = b < a ? b : a; }
int calc(int x1, int x2, int y1, int y2, int z1, int z2) {
  if (x1 > a - 1 || y1 > b - 1 || z1 > c - 1 || x2 < 0 || y2 < 0 || z2 < 0)
    return 0;
  bmax(x1, 0), bmin(x1, a - 1), bmax(x2, 0), bmin(x2, a - 1);
  bmax(y1, 0), bmin(y1, b - 1), bmax(y2, 0), bmin(y2, b - 1);
  bmax(z1, 0), bmin(z1, c - 1), bmax(z2, 0), bmin(z2, c - 1);
  int x = x2 - x1 + 1, y = y2 - y1 + 1, z = z2 - z1 + 1;
  return int((ll)x * y % MOD * z % MOD);
}

void nextblock(int x, int y, int z, int &xx, int &yy, int &zz) {
  xx = x + 1;
  yy = int((ll)xx * b / a);
  zz = int((ll)xx * c / a);
  if (yy == y && zz == z)
    return;
  yy = y + 1;
  xx = int((ll)yy * a / b);
  zz = int((ll)yy * c / b);
  if (xx == x && zz == z)
    return;
  zz = z + 1;
  xx = int((ll)zz * a / c);
  yy = int((ll)zz * b / c);
  if (xx == x && yy == y)
    return;
  printf("nextblock(%d, %d, %d)\\n", x, y, z);
  assert(0);
}
bool test(int x, int y, int z, int xx, int yy, int zz) {
  return false;
  if (xx < x || yy < y || zz < z)
    return false;
  if ((x < d && xx != x) || (y < d && yy != y) || (z < d && zz != z) ||
      (xx >= a - 1 - d && xx != x) || (yy >= b - 1 - d && yy != y) ||
      (zz >= c - 1 - d && zz != z))
    return false;
  else
    return true;
}
void jumpx(int x, int y, int z, int &xx, int &yy, int &zz) {
  int low = x, high = a - 1;
  while (low < high) {
    int mid = (low + high + 1) >> 1;
    int tx = mid;
    int ty = int((ll)tx * b / a);
    int tz = int((ll)tx * c / a);
    if (test(x, y, z, tx, ty, tz))
      low = mid;
    else
      high = mid - 1;
  }
  int tx = low;
  int ty = int((ll)tx * b / a);
  int tz = int((ll)tx * c / a);
  bmax(xx, tx), bmax(yy, ty), bmax(zz, tz);
}
void jumpy(int x, int y, int z, int &xx, int &yy, int &zz) {
  int low = y, high = b - 1;
  while (low < high) {
    int mid = (low + high + 1) >> 1;
    int ty = mid;
    int tx = int((ll)ty * a / b);
    int tz = int((ll)ty * c / b);
    if (test(x, y, z, tx, ty, tz))
      low = mid;
    else
      high = mid - 1;
  }
  int ty = low;
  int tx = int((ll)ty * a / b);
  int tz = int((ll)ty * c / b);
  bmax(xx, tx), bmax(yy, ty), bmax(zz, tz);
}
void jumpz(int x, int y, int z, int &xx, int &yy, int &zz) {
  int low = z, high = c - 1;
  while (low < high) {
    int mid = (low + high + 1) >> 1;
    int tz = mid;
    int ty = int((ll)tz * b / c);
    int tx = int((ll)tz * a / c);
    if (test(x, y, z, tx, ty, tz))
      low = mid;
    else
      high = mid - 1;
  }
  int tz = low;
  int ty = int((ll)tz * b / c);
  int tx = int((ll)tz * a / c);
  bmax(xx, tx), bmax(yy, ty), bmax(zz, tz);
}
void jumpnext(int x, int y, int z, int &xx, int &yy, int &zz) {
  xx = x, yy = y, zz = z;
  jumpx(x, y, z, xx, yy, zz);
  jumpy(x, y, z, xx, yy, zz);
  jumpz(x, y, z, xx, yy, zz);
}

int x[MAXN], y[MAXN], z[MAXN], v[MAXN], sz;
bool checkend() {
  return x[sz - 1] == a - 1 && y[sz - 1] == b - 1 && z[sz - 1] == c - 1;
}
void solve() {
  x[sz] = y[sz] = z[sz] = 0;
  v[sz++] = calc(-d, d, -d, d, -d, d);
  while (!checkend()) {
    jumpnext(x[sz - 1], y[sz - 1], z[sz - 1], x[sz], y[sz], z[sz]);
    int xx = x[sz], yy = y[sz], zz = z[sz];
    // printf( "x = %d, y = %d, z = %d, (pre)\\n", xx, yy, zz );
    nextblock(xx, yy, zz, x[sz], y[sz], z[sz]);
    if (xx != x[sz]) {
      v[sz] = calc(x[sz] + d, x[sz] + d, y[sz] - d, y[sz] + d, z[sz] - d,
                   z[sz] + d);
    } else if (yy != y[sz]) {
      v[sz] = calc(x[sz] - d, x[sz] + d, y[sz] + d, y[sz] + d, z[sz] - d,
                   z[sz] + d);
    } else if (zz != z[sz]) {
      v[sz] = calc(x[sz] - d, x[sz] + d, y[sz] - d, y[sz] + d, z[sz] + d,
                   z[sz] + d);
    }
    // printf( "x = %d, y = %d, z = %d, sz = %d\\n", x[sz], y[sz], z[sz], sz );
    ++sz;
  }
  int ans = 0;
  for (int i = 1; i < sz; ++i) {
    ll cnt = (ll)x[i] - x[i - 1] + y[i] - y[i - 1] + z[i] - z[i - 1];
    ans = int((ans + cnt % MOD * v[i - 1]) % MOD);
  }
  printf("%d\\n", (ans + (d == 0)) % MOD);
}

int main() {
  _w = scanf("%d%d%d%d", &a, &b, &c, &d);
  solve();
  return 0;
}