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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pi;
typedef pair<double, double> pd;
typedef pair<double, ll> pdl;
#define F first
#define S second
const ll E = 1e18 + 7;
const ll MOD = 1000000007;

template <typename T, typename E> struct LinkCutTree {
  struct Node {
    Node *l, *r, *p;
    size_t sz; // tree size (only for root)
    int idx;
    bool rev;
    T val, dat;
    E laz;
    Node() : sz(1) {}
    Node(int idx, T val, E laz)
        : sz(1), idx(idx), rev(0), val(val), dat(val), laz(laz) {
      l = r = p = nullptr;
    }
    bool is_root() { return !p || (p->l != this && p->r != this); }
  };

  using F = function<T(T, T)>;
  using G = function<T(T, E)>;
  using H = function<E(E, E)>;
  using S = function<T(T)>;
  F f;
  G g;
  H h;
  S s;
  T ti;
  E ei;

  const size_t LIM = 1e6;
  vector<Node> pool;
  size_t ptr;

  LinkCutTree(F f, G g, H h, T ti, E ei)
      : f(f), g(g), h(h), ti(ti), ei(ei), pool(LIM), ptr(0) {
    s = [](T a) { return a; };
  }

  LinkCutTree(F f, G g, H h, S s, T ti, E ei)
      : f(f), g(g), h(h), s(s), ti(ti), ei(ei), pool(LIM), ptr(0) {}

  inline Node *create() { return &pool[ptr++]; }

  inline Node *create(int idx, T v) {
    return &(pool[ptr++] = Node(idx, v, ei));
  }

  void propagate(Node *t, E v) {
    t->laz = h(t->laz, v);
    t->val = g(t->val, v);
    t->dat = g(t->dat, v);
  }

  void toggle(Node *t) {
    swap(t->l, t->r);
    t->dat = s(t->dat);
    t->rev ^= 1;
  }

  void eval(Node *t) {
    if (t->laz != ei) {
      if (t->l)
        propagate(t->l, t->laz);
      if (t->r)
        propagate(t->r, t->laz);
      t->laz = ei;
    }
    if (t->rev) {
      if (t->l)
        toggle(t->l);
      if (t->r)
        toggle(t->r);
      t->rev = false;
    }
  }

  void recalc(Node *t) {
    t->dat = t->val;
    if (t->l)
      t->dat = f(t->l->dat, t->dat);
    if (t->r)
      t->dat = f(t->dat, t->r->dat);
  }

  void rotR(Node *t) {
    Node *x = t->p, *y = x->p;
    x->sz -= t->sz;
    t->sz += x->sz;
    if ((x->l = t->r))
      t->r->p = x, x->sz += x->l->sz;
    t->r = x;
    x->p = t;
    recalc(x);
    recalc(t);
    if ((t->p = y)) {
      if (y->l == x)
        y->l = t;
      if (y->r == x)
        y->r = t;
      recalc(y);
    }
  }

  void rotL(Node *t) {
    Node *x = t->p, *y = x->p;
    x->sz -= t->sz;
    t->sz += x->sz;
    if ((x->r = t->l))
      t->l->p = x, x->sz += x->r->sz;
    t->l = x;
    x->p = t;
    recalc(x);
    recalc(t);
    if ((t->p = y)) {
      if (y->l == x)
        y->l = t;
      if (y->r == x)
        y->r = t;
      recalc(y);
    }
  }

  void splay(Node *t) {
    eval(t);
    while (!t->is_root()) {
      Node *q = t->p;
      if (q->is_root()) {
        eval(q);
        eval(t);
        if (q->l == t)
          rotR(t);
        else
          rotL(t);
      } else {
        auto *r = q->p;
        eval(r);
        eval(q);
        eval(t);
        if (r->l == q) {
          if (q->l == t)
            rotR(q), rotR(t);
          else
            rotL(t), rotR(t);
        } else {
          if (q->r == t)
            rotL(q), rotL(t);
          else
            rotR(t), rotL(t);
        }
      }
    }
  }

  Node *expose(Node *t) {
    Node *rp = nullptr;
    for (Node *c = t; c; c = c->p) {
      splay(c);
      c->r = rp;
      recalc(c);
      rp = c;
    }
    splay(t);
    return rp;
  }

  void link(Node *par, Node *c) {
    expose(c);
    expose(par);
    c->p = par;
    par->r = c;
    par->sz += c->sz;
  }

  void cut(Node *c) {
    expose(c);
    Node *par = c->l;
    c->l = nullptr;
    par->p = nullptr;
    c->sz -= par->sz;
  }

  void evert(Node *t) {
    expose(t);
    toggle(t);
    eval(t);
  }

  bool is_connected(Node *a, Node *b) {
    expose(a);
    while (a->l)
      a = a->l;
    expose(b);
    while (b->l)
      b = b->l;
    return expose(a) == expose(b);
  }

  Node *lca(Node *a, Node *b) {
    expose(a);
    return expose(b);
  }

  T query(Node *t) {
    expose(t);
    return t->dat;
  }

  void update(Node *t, E v) {
    expose(t);
    propagate(t, v);
    eval(t);
  }
};

// END CUT HERE

template <typename T> struct BIT {
  int n;
  vector<T> bit;
  // 1-indexed
  BIT() : n(-1) {}
  BIT(int n_, T d) : n(n_), bit(n_ + 1, d) {}

  T sum(int i) {
    T s = bit[0];
    for (int x = i; x > 0; x -= (x & -x))
      s += bit[x];
    return s;
  }
  void add(int i, T a) {
    if (i == 0)
      return;
    for (int x = i; x <= n; x += (x & -x))
      bit[x] += a;
  }

  int lower_bound(int w) {
    if (w <= 0)
      return 0;
    int x = 0, r = 1;
    while (r < n)
      r <<= 1;
    for (int k = r; k > 0; k >>= 1) {
      if (x + k <= n && bit[x + k] < w) {
        w -= bit[x + k];
        x += k;
      }
    }
    return x + 1;
  }

  T sum0(int i) { return sum(i + 1); }
  void add0(int i, T a) { add(i + 1, a); }

  T query(int l, int r) { return sum(r - 1) - sum(l - 1); }

  T query0(int l, int r) { return sum(r) - sum(l); }
};

class LCA {
private:
  typedef pair<ll, vector<ll>> node; // depth,parents
  ll root;
  ll v;
  vector<node> tree;
  vector<vector<ll>> E;
  ll High; // 高さのlog

  void bfs() {
    tree[root] = {0, {root}};
    queue<ll> q;
    q.push(root);
    vector<bool> done(v, false);
    while (!q.empty()) {
      ll where = q.front();
      q.pop();
      if (done[where]) {
        continue;
      }
      done[where] = true;
      for (int i = 0; i < E[where].size(); i++) {
        if (!done[E[where][i]]) {
          tree[E[where][i]].F = tree[where].F + 1;
          tree[E[where][i]].S = {where};
          q.push(E[where][i]);
        }
      }
    }
  }

public:
  LCA(ll v, ll root) : v(v), root(root) {
    tree.resize(v);
    E.resize(v);
  }

  // 双方向のエッジでもよい
  void add_edge(ll from, ll to) { E[from].push_back(to); }

  // searchの前に行う
  void mk_tree() {
    bfs();
    bool j = true;
    for (int i = 0; j; i++) {
      j = false;
      for (int t = 0; t < v; t++) {
        ll P = tree[t].S[i];
        P = tree[P].S[i];
        tree[t].S.push_back(P);
        if (P != root) {
          j = true;
        }
      }
    }
    High = tree[root].S.size();
  }

  ll search_parent(ll a, ll h) {
    if (tree[a].F <= h) {
      return root;
    }
    for (ll i = High - 1; i >= 0; i--) {
      if ((1 << i) & h) {
        a = tree[a].S[i];
      }
    }
    return a;
  }

  ll search_lca(ll a, ll b) {
    ll dif = tree[a].F - tree[b].F;
    if (0 > dif) {
      swap(a, b);
      dif = abs(dif);
    }
    a = search_parent(a, dif);
    for (ll i = High - 1; i >= 0; i--) {
      if (tree[a].S[i] != tree[b].S[i]) {
        a = tree[a].S[i];
        b = tree[b].S[i];
      }
    }
    while (a != b) {
      a = tree[a].S[0];
      b = tree[b].S[0];
    }
    return a;
  }

  ll high(ll a) { return tree[a].F; }
};

int main() {
  int n;
  while (cin >> n) {
    if (n == 0) {
      break;
    }
    int q;
    cin >> q;
    using LCT = LinkCutTree<int, int>;
    LCT::F f = [](int a, int b) { return a + b; };
    LCT lc(f, f, f, 0, 0);
    vector<int> P(n);
    vector<LCT::Node *> v(n);
    LCA lca(n, 0);
    for (int i = 0; i < n; i++)
      v[i] = lc.create(i, 0);
    ll ans = 0;
    for (int i = 1; i < n; i++) {
      int k;
      cin >> k;
      k--;
      lc.link(v[k], v[i]);
      P[i] = k;
      lca.add_edge(k, i);
    }
    lca.mk_tree();
    for (int i = 0; i < q; i++) {
      char c;
      cin >> c;
      if (c == 'M') {
        int a;
        cin >> a;
        a--;
        lc.expose(v[a]);
        v[a]->val = f(v[a]->val, 1);
      } else {
        int a;
        cin >> a;
        a--;
        if (a == 0) {
          ans++;
          continue;
        }
        // a=P[a];
        lc.expose(v[a]);
        int D = v[a]->dat;
        if (D == 0 || a == 0) {
          ans++;
          continue;
        }
        int l = 1, r = n;
        while (r - l > 1) {
          int m = l + (r - l) / 2;
          ll p = lca.search_parent(a, m);
          lc.expose(v[p]);
          if (D - v[p]->dat > 0) {
            r = m;
          } else {
            l = m;
          }
        }
        bool done = false;
        for (int i = l; i <= r; i++) {
          ll p = lca.search_parent(a, i);
          lc.expose(v[p]);
          if (D - v[p]->dat > 0) {
            ans += lca.search_parent(a, i - 1) + 1;
            done = true;
            break;
          }
        }
        if (!done) {
          ans++;
        }
      }
    }
    cout << ans << endl;
  }

  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pi;
typedef pair<double, double> pd;
typedef pair<double, ll> pdl;
#define F first
#define S second
const ll E = 1e18 + 7;
const ll MOD = 1000000007;

template <typename T, typename E> struct LinkCutTree {
  struct Node {
    Node *l, *r, *p;
    size_t sz; // tree size (only for root)
    int idx;
    bool rev;
    T val, dat;
    E laz;
    Node() : sz(1) {}
    Node(int idx, T val, E laz)
        : sz(1), idx(idx), rev(0), val(val), dat(val), laz(laz) {
      l = r = p = nullptr;
    }
    bool is_root() { return !p || (p->l != this && p->r != this); }
  };

  using F = function<T(T, T)>;
  using G = function<T(T, E)>;
  using H = function<E(E, E)>;
  using S = function<T(T)>;
  F f;
  G g;
  H h;
  S s;
  T ti;
  E ei;

  const size_t LIM = 1e6;
  vector<Node> pool;
  size_t ptr;

  LinkCutTree(F f, G g, H h, T ti, E ei)
      : f(f), g(g), h(h), ti(ti), ei(ei), pool(LIM), ptr(0) {
    s = [](T a) { return a; };
  }

  LinkCutTree(F f, G g, H h, S s, T ti, E ei)
      : f(f), g(g), h(h), s(s), ti(ti), ei(ei), pool(LIM), ptr(0) {}

  inline Node *create() { return &pool[ptr++]; }

  inline Node *create(int idx, T v) {
    return &(pool[ptr++] = Node(idx, v, ei));
  }

  void propagate(Node *t, E v) {
    t->laz = h(t->laz, v);
    t->val = g(t->val, v);
    t->dat = g(t->dat, v);
  }

  void toggle(Node *t) {
    swap(t->l, t->r);
    t->dat = s(t->dat);
    t->rev ^= 1;
  }

  void eval(Node *t) {
    if (t->laz != ei) {
      if (t->l)
        propagate(t->l, t->laz);
      if (t->r)
        propagate(t->r, t->laz);
      t->laz = ei;
    }
    if (t->rev) {
      if (t->l)
        toggle(t->l);
      if (t->r)
        toggle(t->r);
      t->rev = false;
    }
  }

  void recalc(Node *t) {
    t->dat = t->val;
    if (t->l)
      t->dat = f(t->l->dat, t->dat);
    if (t->r)
      t->dat = f(t->dat, t->r->dat);
  }

  void rotR(Node *t) {
    Node *x = t->p, *y = x->p;
    x->sz -= t->sz;
    t->sz += x->sz;
    if ((x->l = t->r))
      t->r->p = x, x->sz += x->l->sz;
    t->r = x;
    x->p = t;
    recalc(x);
    recalc(t);
    if ((t->p = y)) {
      if (y->l == x)
        y->l = t;
      if (y->r == x)
        y->r = t;
      recalc(y);
    }
  }

  void rotL(Node *t) {
    Node *x = t->p, *y = x->p;
    x->sz -= t->sz;
    t->sz += x->sz;
    if ((x->r = t->l))
      t->l->p = x, x->sz += x->r->sz;
    t->l = x;
    x->p = t;
    recalc(x);
    recalc(t);
    if ((t->p = y)) {
      if (y->l == x)
        y->l = t;
      if (y->r == x)
        y->r = t;
      recalc(y);
    }
  }

  void splay(Node *t) {
    eval(t);
    while (!t->is_root()) {
      Node *q = t->p;
      if (q->is_root()) {
        eval(q);
        eval(t);
        if (q->l == t)
          rotR(t);
        else
          rotL(t);
      } else {
        auto *r = q->p;
        eval(r);
        eval(q);
        eval(t);
        if (r->l == q) {
          if (q->l == t)
            rotR(q), rotR(t);
          else
            rotL(t), rotR(t);
        } else {
          if (q->r == t)
            rotL(q), rotL(t);
          else
            rotR(t), rotL(t);
        }
      }
    }
  }

  Node *expose(Node *t) {
    Node *rp = nullptr;
    for (Node *c = t; c; c = c->p) {
      splay(c);
      c->r = rp;
      recalc(c);
      rp = c;
    }
    splay(t);
    return rp;
  }

  void link(Node *par, Node *c) {
    expose(c);
    expose(par);
    c->p = par;
    par->r = c;
    par->sz += c->sz;
  }

  void cut(Node *c) {
    expose(c);
    Node *par = c->l;
    c->l = nullptr;
    par->p = nullptr;
    c->sz -= par->sz;
  }

  void evert(Node *t) {
    expose(t);
    toggle(t);
    eval(t);
  }

  bool is_connected(Node *a, Node *b) {
    expose(a);
    while (a->l)
      a = a->l;
    expose(b);
    while (b->l)
      b = b->l;
    return expose(a) == expose(b);
  }

  Node *lca(Node *a, Node *b) {
    expose(a);
    return expose(b);
  }

  T query(Node *t) {
    expose(t);
    return t->dat;
  }

  void update(Node *t, E v) {
    expose(t);
    propagate(t, v);
    eval(t);
  }
};

// END CUT HERE

template <typename T> struct BIT {
  int n;
  vector<T> bit;
  // 1-indexed
  BIT() : n(-1) {}
  BIT(int n_, T d) : n(n_), bit(n_ + 1, d) {}

  T sum(int i) {
    T s = bit[0];
    for (int x = i; x > 0; x -= (x & -x))
      s += bit[x];
    return s;
  }
  void add(int i, T a) {
    if (i == 0)
      return;
    for (int x = i; x <= n; x += (x & -x))
      bit[x] += a;
  }

  int lower_bound(int w) {
    if (w <= 0)
      return 0;
    int x = 0, r = 1;
    while (r < n)
      r <<= 1;
    for (int k = r; k > 0; k >>= 1) {
      if (x + k <= n && bit[x + k] < w) {
        w -= bit[x + k];
        x += k;
      }
    }
    return x + 1;
  }

  T sum0(int i) { return sum(i + 1); }
  void add0(int i, T a) { add(i + 1, a); }

  T query(int l, int r) { return sum(r - 1) - sum(l - 1); }

  T query0(int l, int r) { return sum(r) - sum(l); }
};

class LCA {
private:
  typedef pair<ll, vector<ll>> node; // depth,parents
  ll root;
  ll v;
  vector<node> tree;
  vector<vector<ll>> E;
  ll High; // 高さのlog

  void bfs() {
    tree[root] = {0, {root}};
    queue<ll> q;
    q.push(root);
    vector<bool> done(v, false);
    while (!q.empty()) {
      ll where = q.front();
      q.pop();
      if (done[where]) {
        continue;
      }
      done[where] = true;
      for (int i = 0; i < E[where].size(); i++) {
        if (!done[E[where][i]]) {
          tree[E[where][i]].F = tree[where].F + 1;
          tree[E[where][i]].S = {where};
          q.push(E[where][i]);
        }
      }
    }
  }

public:
  LCA(ll v, ll root) : v(v), root(root) {
    tree.resize(v);
    E.resize(v);
  }

  // 双方向のエッジでもよい
  void add_edge(ll from, ll to) { E[from].push_back(to); }

  // searchの前に行う
  void mk_tree() {
    bfs();
    bool j = true;
    for (int i = 0; j; i++) {
      j = false;
      for (int t = 0; t < v; t++) {
        ll P = tree[t].S[i];
        P = tree[P].S[i];
        tree[t].S.push_back(P);
        if (P != root) {
          j = true;
        }
      }
    }
    High = tree[root].S.size();
  }

  ll search_parent(ll a, ll h) {
    if (tree[a].F <= h) {
      return root;
    }
    for (ll i = High - 1; i >= 0; i--) {
      if ((1 << i) & h) {
        a = tree[a].S[i];
      }
    }
    return a;
  }

  ll search_lca(ll a, ll b) {
    ll dif = tree[a].F - tree[b].F;
    if (0 > dif) {
      swap(a, b);
      dif = abs(dif);
    }
    a = search_parent(a, dif);
    for (ll i = High - 1; i >= 0; i--) {
      if (tree[a].S[i] != tree[b].S[i]) {
        a = tree[a].S[i];
        b = tree[b].S[i];
      }
    }
    while (a != b) {
      a = tree[a].S[0];
      b = tree[b].S[0];
    }
    return a;
  }

  ll high(ll a) { return tree[a].F; }
};

int main() {
  int n;
  while (cin >> n) {
    if (n == 0) {
      break;
    }
    int q;
    cin >> q;
    using LCT = LinkCutTree<int, int>;
    LCT::F f = [](int a, int b) { return a + b; };
    LCT lc(f, f, f, 0, 0);
    vector<int> P(n);
    vector<LCT::Node *> v(n);
    LCA lca(n, 0);
    for (int i = 0; i < n; i++)
      v[i] = lc.create(i, 0);
    ll ans = 0;
    for (int i = 1; i < n; i++) {
      int k;
      cin >> k;
      k--;
      lc.link(v[k], v[i]);
      P[i] = k;
      lca.add_edge(k, i);
    }
    lca.mk_tree();
    for (int i = 0; i < q; i++) {
      char c;
      cin >> c;
      if (c == 'M') {
        int a;
        cin >> a;
        a--;
        lc.expose(v[a]);
        v[a]->val = f(v[a]->val, 1);
      } else {
        int a;
        cin >> a;
        if (a == 1) {
          assert(false);
        }
        a = P[a - 1];
        lc.expose(v[a]);
        int D = v[a]->dat;
        if (D == 0 || a == 0) {
          ans++;
          continue;
        }
        int l = 1, r = n;
        while (r - l > 1) {
          int m = l + (r - l) / 2;
          ll p = lca.search_parent(a, m);
          lc.expose(v[p]);
          if (D - v[p]->dat > 0) {
            r = m;
          } else {
            l = m + 1;
          }
        }
        for (int i = l; i <= r; i++) {
          ll p = lca.search_parent(a, i);
          lc.expose(v[p]);
          if (D - v[p]->dat > 0) {
            ans += lca.search_parent(a, i - 1) + 1;
            break;
          }
        }
      }
    }
    cout << ans << endl;
  }

  return 0;
}