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

#include <algorithm>
#include <assert.h>
#include <ctype.h>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
static const long long BASE = 1000000;
static const int BW = 6;
static const int MAXDIGIT = 20;

struct Long {
  long long digit[MAXDIGIT];
  int size;
  explicit Long(int size = 1, long long a = 0) : size(size) {
    memset(digit, 0, sizeof(digit));
    digit[0] = a;
  }
};
const Long ZERO(1, 0), ONE(1, 1);

// Comparators
bool operator<(const Long &x, const Long &y) {
  if (x.size != y.size) {
    return x.size < y.size;
  }
  for (int i = x.size - 1; i >= 0; --i) {
    if (x.digit[i] != y.digit[i]) {
      return x.digit[i] < y.digit[i];
    }
  }
  return false;
}
bool operator>(const Long &x, const Long &y) { return y < x; }
bool operator<=(const Long &x, const Long &y) { return !(y < x); }
bool operator>=(const Long &x, const Long &y) { return !(x < y); }
bool operator!=(const Long &x, const Long &y) { return x < y || y < x; }
bool operator==(const Long &x, const Long &y) { return !(x < y) && !(y < x); }

// Input/Output
ostream &operator<<(ostream &os, const Long &x) {
  os << x.digit[x.size - 1];
  for (int i = x.size - 2; i >= 0; i--) {
    os << setw(BW) << setfill('0') << x.digit[i];
  }
  return os;
}
void print(const Long &x) {
  printf("%lld", x.digit[x.size - 1]);
  for (int i = x.size - 2; i >= 0; --i) {
    printf("%04lld", x.digit[i]);
  }
}

// Utilities
Long normal(Long x) {
  long long c = 0;
  for (int i = 0; i < x.size; i++) {
    while (x.digit[i] < 0) {
      x.digit[i + 1] -= 1;
      x.digit[i] += BASE;
    }
    long long a = x.digit[i] + c;
    x.digit[i] = a % BASE;
    c = a / BASE;
  }
  for (; c > 0; c /= BASE) {
    x.digit[x.size++] = c % BASE;
  }
  while (x.size > 1 && x.digit[x.size - 1] == 0) {
    --x.size;
  }
  return x;
}

Long convert(long long a) { return normal(Long(1, a)); }

Long convert(const string &s) {
  Long x;
  int i = s.size() % BW;
  if (i > 0)
    i -= BW;
  for (; i < (int)s.size(); i += BW) {
    long long a = 0;
    for (int j = 0; j < BW; j++) {
      a = 10 * a + (i + j >= 0 ? s[i + j] - '0' : 0);
    }
    x.digit[x.size++] = a;
  }
  reverse(x.digit, x.digit + x.size);
  return normal(x);
}

// Basic Operations
Long operator+(Long x, const Long &y) {
  if (x.size < y.size) {
    x.size = y.size;
  }
  for (int i = 0; i < y.size; i++) {
    x.digit[i] += y.digit[i];
  }
  return normal(x);
}

Long operator-(Long x, const Long &y) {
  assert(x >= y);
  for (int i = 0; i < y.size; i++) {
    x.digit[i] -= y.digit[i];
  }
  return normal(x);
}

Long operator*(const Long &x, const Long &y) {
  Long z(x.size + y.size);
  for (int i = 0; i < x.size; i++) {
    for (int j = 0; j < y.size; j++) {
      z.digit[i + j] += x.digit[i] * y.digit[j];
    }
  }
  return normal(z);
}

Long operator*(Long x, long long a) {
  for (int i = 0; i < x.size; i++) {
    x.digit[i] *= a;
  }
  return normal(x);
}

pair<Long, long long> divmod(Long x, const long long &a) {
  long long c = 0, t;
  for (int i = x.size - 1; i >= 0; --i) {
    t = BASE * c + x.digit[i];
    x.digit[i] = t / a;
    c = t % a;
  }
  return make_pair(normal(x), c);
}

Long operator/(const Long &x, const long long &a) { return divmod(x, a).first; }
long long operator%(const Long &x, const long long &a) {
  return divmod(x, a).second;
}

pair<Long, Long> divmod(Long x, Long y) {
  if (x.size < y.size) {
    return pair<Long, Long>(ZERO, x);
  }
  int F = BASE / (y.digit[y.size - 1] + 1); // multiplying good-factor
  x = x * F;
  y = y * F;
  Long z(x.size - y.size + 1);
  for (int k = z.size - 1, i = x.size - 1; k >= 0; k--, i--) {
    z.digit[k] = (i + 1 < x.size ? x.digit[i + 1] : 0) * BASE + x.digit[i];
    z.digit[k] /= y.digit[y.size - 1];
    Long t(k + y.size);
    for (int m = 0; m < y.size; m++) {
      t.digit[k + m] = z.digit[k] * y.digit[m];
    }
    t = normal(t);
    while (x < t) {
      z.digit[k] -= 1;
      for (int m = 0; m < y.size; m++) {
        t.digit[k + m] -= y.digit[m];
      }
      t = normal(t);
    }
    x = x - t;
  }
  return make_pair(normal(z), x / F);
}
Long operator/(Long x, Long y) { return divmod(x, y).first; }
Long operator%(Long x, Long y) { return divmod(x, y).second; }

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define DEC(i, s) for (int i = (s); i >= 0; i--)

#define SIZE(v) (int)((v).size())
#define MEMSET(v, h) memset((v), h, sizeof(v))
#define FIND(m, w) ((m).find(w) != (m).end())

struct Node {
  Long length;
  Long size;
  ll loop;
  char c;
  vector<Node> child;
  Node() : loop(1), c(0) { ; }
};

char str[1000];

Node parse(ll &index) {
  ll loop = 1;
  Node ret;
  if (isalpha(str[index])) {
    ret.length = convert(1);
    ret.c = str[index];
    index++;
  } else if (isdigit(str[index])) {
    loop = atoi(str + index);
    while (isdigit(str[index])) {
      index++;
    }
    if (isalpha(str[index])) {
      ret.child.push_back(parse(index));
      ret.length = ret.length + ret.child[ret.child.size() - 1].size;
    } else {
      assert(str[index] == '(');
      index++;
      while (str[index] != ')') {
        ret.child.push_back(parse(index));
        ret.length = ret.length + ret.child[ret.child.size() - 1].size;
      }
      assert(str[index] == ')');
      index++;
    }
  }
  ret.size = ret.length * loop;
  ret.loop = loop;
  return ret;
}

char nodechar(const Node &node, Long &n) {
  if (node.size <= n) {
    return '0';
  }
  n = n % node.length;
  if (n == convert(0) && node.c != 0) {
    return node.c;
  }
  REP(i, node.child.size()) {
    const Node &target = node.child[i];
    if (target.size > n) {
      return nodechar(target, n);
    }
    n = n - target.size;
  }
  assert(false);
  return 0;
}

int main() {
  ll n;
  while (scanf("%s %lld", str, &n), str[0] != '0' || n) {
    ll index = 0;
    Node root;
    while (str[index] != '\\0') {
      root.child.push_back(parse(index));
      root.size = root.size + root.child[root.child.size() - 1].size;
      root.length = root.length + root.child[root.child.size() - 1].size;
    }
    Long longn = convert(n);
    printf("%c\\n", nodechar(root, longn));
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <ctype.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define DEC(i, s) for (int i = (s); i >= 0; i--)

#define SIZE(v) (int)((v).size())
#define MEMSET(v, h) memset((v), h, sizeof(v))
#define FIND(m, w) ((m).find(w) != (m).end())

struct Node {
  ll length;
  ll size;
  ll loop;
  char c;
  vector<Node> child;
  Node() : length(0), size(0), loop(1), c(0) { ; }
};

char str[1000];

Node parse(ll &index, ll loop) {
  Node ret;
  if (isalpha(str[index])) {
    ret.length = 1;
    ret.c = str[index];
    index++;
  } else if (isdigit(str[index])) {
    ll nloop = atoi(str + index);
    while (isdigit(str[index])) {
      index++;
    }
    if (isalpha(str[index])) {
      ret.child.push_back(parse(index, nloop));
      ret.length += ret.child[ret.child.size() - 1].size;
    } else {
      assert(str[index] == '(');
      index++;
      while (str[index] != ')') {
        ret.child.push_back(parse(index, nloop));
        ret.length += ret.child[ret.child.size() - 1].size;
      }
      assert(str[index] == ')');
      index++;
    }
  }
  ret.size = ret.length * loop;
  ret.loop = loop;
  return ret;
}

char nodechar(const Node &node, int n) {
  if (node.size <= n) {
    return '0';
  }
  n %= node.length;
  if (n == 0 && node.c != 0) {
    return node.c;
  }
  REP(i, node.child.size()) {
    const Node &target = node.child[i];
    if (target.size > n) {
      return nodechar(target, n);
    }
    n -= target.size;
  }
  assert(false);
  return 0;
}

int main() {
  ll n;
  while (scanf("%s %lld", str, &n), str[0] != '0' || n) {
    ll index = 0;
    Node root;
    while (str[index] != '\\0') {
      root.child.push_back(parse(index, 1));
      root.size += root.child[root.child.size() - 1].size;
      root.length += root.child[root.child.size() - 1].size;
    }
    printf("%c\\n", nodechar(root, n));
  }
}