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

#include <bits/stdc++.h>
#define INF 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const int PLUS = -1;
const int MUL = -2;

class expr {
public:
  bool f = true;
  ll l = 0, m = 0, r = 0;
  expr() {}
  expr(bool ff, ll lv, ll mv, ll rv) {
    f = ff;
    l = lv;
    m = mv;
    r = rv;
  }
};

expr merge(expr el, expr er, int op) {
  expr res;
  if (op == PLUS) {
    res.f = false;
    if (el.f && er.f) {
      res.l = el.m;
      res.r = er.m;
      res.m = 0;
    } else if (el.f) {
      res.l = el.m;
      res.m = min(INF, er.l + er.m);
      res.r = er.r;
    } else if (er.f) {
      res.l = el.l;
      res.m = min(INF, el.m + el.r);
      res.r = er.m;
    } else {
      res.l = el.l;
      // maybe overflow a+b+c+d
      res.m = min(INF, el.m + el.r + er.l + er.m);
      res.r = er.r;
    }
  } else if (op == MUL) {
    res.f = el.f && er.f;
    if (el.f && er.f) {
      res.l = 0;
      res.m = min(INF, el.m * er.m);
      res.r = 0;
    } else if (el.f) {
      res.l = min(INF, el.m * er.l);
      res.m = er.m;
      res.r = er.r;
    } else if (er.f) {
      res.l = el.l;
      res.m = el.m;
      res.r = min(INF, el.r * er.m);
    } else {
      res.l = el.l;
      // maybe overflow a+b*c+d
      res.m = min(INF, el.m + el.r * er.l + er.m);
      res.r = er.r;
    }
  } else {
    res = el;
  }
  return res;
}

struct segtree {
  int N;
  expr ex[1 << 21];
  int op[1 << 21];
  segtree() {}
  void memsetN(int n) {
    N = 1;
    while (N < n) {
      N *= 2;
    }

    for (int i = 0; i < N * 2; i++) {
      ex[i] = expr(true, 0, 1, 0);
      op[i] = MUL;
    }
  }
  void init(vector<ll> &v, int k, int l, int r) {
    if ((r - l) == 1) {
      if (l * 2 < v.size())
        ex[k] = expr(true, 0, v[l * 2], 0);
      return;
    }
    int mid = (l + r) / 2;
    init(v, k * 2 + 1, l, mid);
    init(v, k * 2 + 2, mid, r);
    if (2 * mid - 1 < v.size())
      op[k] = v[2 * mid - 1];
    ex[k] = merge(ex[k * 2 + 1], ex[k * 2 + 2], op[k]);
  }
  expr query(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return expr(true, 0, 1, 0);
    if (a <= l && r <= b)
      return ex[k];
    int mid = (l + r) / 2;
    expr el = query(a, b, k * 2 + 1, l, mid);
    expr er = query(a, b, k * 2 + 2, mid, r);
    if (mid <= a)
      return er;
    if (b <= mid)
      return el;
    // printf("%d %d %d %d %d %d (%lld,%lld,%lld),%d
    // (%lld,%lld,%lld),%d\\n",a,b,k,l,r,op[k],el.l,el.m,el.r,el.f?1:0,er.l,er.m,er.r,er.f?1:0);
    return merge(el, er, op[k]);
  }
  ll getval(int l, int r) {
    expr res = query(l, r, 0, 0, N);
    return min(INF, res.l + res.m + res.r);
  }
};

segtree seg;

ll n;
string str;
int pos = 0;
ll ans = 0;

// v {num, op, num, op, ...}
ll solve2(vector<ll> v) {
  int m = v.size() / 2 + 1;
  seg.memsetN(m);
  seg.init(v, 0, 0, seg.N);
  int r = 0;
  int r2 = 0;
  for (int i = 0; i < m; i++) {
    ll tmp = 0;
    r = max(i, r);
    r2 = max(i, r2);
    while (r < m && (tmp = seg.getval(i, r + 1)) <= n) {
      r++;
    }
    while (r2 < m && (tmp = seg.getval(i, r2 + 1)) < n) {
      r2++;
    }
    ans += (r - r2);
  }
  return seg.getval(0, m);
}

ll solve() {
  vector<ll> v;
  while (pos != (int)str.size()) {
    char c = str[pos];
    if (c == '(') {
      pos++;
      v.push_back(solve());
    }
    if (c == ')') {
      pos++;
      break;
    }
    if (isdigit(c)) {
      pos++;
      v.push_back(c - '0');
    }
    if (c == '*') {
      pos++;
      v.push_back(MUL);
    }
    if (c == '+') {
      pos++;
      v.push_back(PLUS);
    }
  }
  return solve2(v);
}

int main(void) {
  while (1) {
    scanf("%lld", &n);
    if (n == 0LL)
      break;
    cin >> str;
    // printf("%d\\n",(int)str.size());
    ans = 0;
    pos = 0;
    solve();
    printf("%lld\\n", ans);
  }
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define INF 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const int PLUS = -1;
const int MUL = -2;

class expr {
public:
  bool f = true;
  ll l = 0, m = 0, r = 0;
  expr() {}
  expr(bool ff, ll lv, ll mv, ll rv) {
    f = ff;
    l = lv;
    m = mv;
    r = rv;
  }
};

expr merge(expr el, expr er, int op) {
  expr res;
  if (op == PLUS) {
    res.f = false;
    if (el.f && er.f) {
      res.l = el.m;
      res.r = er.m;
      res.m = 0;
    } else if (el.f) {
      res.l = el.m;
      res.m = min(INF, er.l + er.m);
      res.r = er.r;
    } else if (er.f) {
      res.l = el.l;
      res.m = min(INF, el.m + el.r);
      res.r = er.m;
    } else {
      res.l = el.l;
      // maybe overflow a+b+c+d
      res.m = min(INF, el.m + el.r + er.l + er.m);
      res.r = er.r;
    }
  } else if (op == MUL) {
    res.f = el.f && er.f;
    if (el.f && er.f) {
      res.l = 0;
      res.m = min(INF, el.m * er.m);
      res.r = 0;
    } else if (el.f) {
      res.l = min(INF, el.m * er.l);
      res.m = er.m;
      res.r = er.r;
    } else if (er.f) {
      res.l = el.l;
      res.m = el.m;
      res.r = min(INF, el.r * er.m);
    } else {
      res.l = el.l;
      // maybe overflow a+b*c+d
      res.m = min(INF, el.m + el.r * er.l + er.m);
      res.r = er.r;
    }
  } else {
    res = el;
  }
  return res;
}

struct segtree {
  int N;
  expr ex[1 << 19];
  int op[1 << 19];
  segtree() {}
  void memsetN(int n) {
    N = 1;
    while (N < n) {
      N *= 2;
    }

    for (int i = 0; i < N * 2; i++) {
      ex[i] = expr(true, 0, 1, 0);
      op[i] = MUL;
    }
  }
  void init(vector<ll> &v, int k, int l, int r) {
    if ((r - l) == 1) {
      if (l * 2 < v.size())
        ex[k] = expr(true, 0, v[l * 2], 0);
      return;
    }
    int mid = (l + r) / 2;
    init(v, k * 2 + 1, l, mid);
    init(v, k * 2 + 2, mid, r);
    if (2 * mid - 1 < v.size())
      op[k] = v[2 * mid - 1];
    ex[k] = merge(ex[k * 2 + 1], ex[k * 2 + 2], op[k]);
  }
  expr query(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return expr(true, 0, 1, 0);
    if (a <= l && r <= b)
      return ex[k];
    int mid = (l + r) / 2;
    expr el = query(a, b, k * 2 + 1, l, mid);
    expr er = query(a, b, k * 2 + 2, mid, r);
    if (mid <= a)
      return er;
    if (b <= mid)
      return el;
    // printf("%d %d %d %d %d %d (%lld,%lld,%lld),%d
    // (%lld,%lld,%lld),%d\\n",a,b,k,l,r,op[k],el.l,el.m,el.r,el.f?1:0,er.l,er.m,er.r,er.f?1:0);
    return merge(el, er, op[k]);
  }
  ll getval(int l, int r) {
    expr res = query(l, r, 0, 0, N);
    return min(INF, res.l + res.m + res.r);
  }
};

segtree seg;

ll n;
string str;
int pos = 0;
ll ans = 0;

// v {num, op, num, op, ...}
ll solve2(vector<ll> v) {
  int m = v.size() / 2 + 1;
  seg.memsetN(m);
  seg.init(v, 0, 0, seg.N);
  int r = 0;
  int r2 = 0;
  for (int i = 0; i < m; i++) {
    ll tmp = 0;
    r = max(i, r);
    r2 = max(i, r2);
    while (r < m && (tmp = seg.getval(i, r + 1)) <= n) {
      r++;
    }
    while (r2 < m && (tmp = seg.getval(i, r2 + 1)) < n) {
      r2++;
    }
    ans += (r - r2);
  }
  return seg.getval(0, m);
}

ll solve() {
  vector<ll> v;
  while (pos != (int)str.size()) {
    char c = str[pos];
    if (c == '(') {
      pos++;
      v.push_back(solve());
    }
    if (c == ')') {
      pos++;
      break;
    }
    if (isdigit(c)) {
      pos++;
      v.push_back(c - '0');
    }
    if (c == '*') {
      pos++;
      v.push_back(MUL);
    }
    if (c == '+') {
      pos++;
      v.push_back(PLUS);
    }
  }
  return solve2(v);
}

int main(void) {
  while (1) {
    scanf("%lld", &n);
    if (n == 0LL)
      break;
    cin >> str;
    ans = 0;
    pos = 0;
    solve();
    printf("%lld\\n", ans);
  }
  return 0;
}