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

#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

struct LCTree {
  typedef int D;
  static const int INF = 1LL << 25;
  static const int DF = 1LL << 25;
  struct Node;
  typedef Node *NP;
  static Node last_d;
  static NP last;
  struct Node {
    NP p, l, r;
    int sz;
    int v, sm, lz;
    int lsm, rsm, ma, mv;
    bool rev;
    Node(D v)
        : p(NULL), l(last), r(last), sz(1), v(v), sm(v), lz(DF), rev(false),
          lsm(max(v, 0)), rsm(max(v, 0)), ma(max(v, 0)), mv(v) {}
    Node(NP l, NP r) : l(l), r(r), sz(0), v(-INF), mv(-INF) {}
    int pos() {
      if (p && p->l == this)
        return -1;
      if (p && p->r == this)
        return 1;
      return 0;
    }
    void rot() {
      NP q = p, qq = q->p;
      int qqp = q->pos();
      if (q->l == this) {
        q->l = r;
        r->p = q;
        r = q;
        q->p = this;
      } else {
        q->r = l;
        l->p = q;
        l = q;
        q->p = this;
      }
      q->update();
      update();
      if ((p = qq) && qqp) {
        if (qq->l == q)
          qq->l = this;
        if (qq->r == q)
          qq->r = this;
        qq->update();
      }
    }
    void splay() {
      supush();
      while (pos()) {
        if (!pos() || !p->pos()) {
          rot();
        } else if (p->pos() == pos()) {
          p->rot();
          rot();
        } else {
          rot();
          rot();
        }
      }
    }
    void expose() {
      NP u = this;
      while (u) {
        u->splay();
        u = u->p;
      }
      u = this;
      while (u->p) {
        u->p->l = u;
        u = u->p;
        u->update();
      }
      splay();
    }
    void push() {
      if (rev) {
        swap(l, r);
        if (l->sz) {
          l->rev ^= true;
          swap(l->lsm, l->rsm);
        }
        if (r->sz) {
          r->rev ^= true;
          swap(r->lsm, r->rsm);
        }
        rev = false;
      }

      if (lz != DF) {
        if (l->sz) {
          l->updata(lz);
        }
        if (r->sz) {
          r->updata(lz);
        }
        lz = DF;
      }
    }
    void supush() {
      if (pos()) {
        p->supush();
      }
      push();
    }
    void updata(D d) {
      v = d;
      sm = sz * d;
      lz = d;
      lsm = rsm = ma = max(0, sm);
      mv = lz;
    }
    NP update() {
      if (this == last)
        return this;
      sz = 1 + l->sz + r->sz;
      sm = v + l->sm + r->sm;
      lsm = max(l->lsm, l->sm + v + r->lsm);
      rsm = max(r->rsm, r->sm + v + l->rsm);
      ma = max(l->ma, r->ma);
      ma = max(ma, l->rsm + v + r->lsm);
      mv = max(l->mv, r->mv);
      mv = max(mv, v);
      return this;
    }
  } *n;
  LCTree() : n(last) {}
  LCTree(NP n) : n(n) {}
  LCTree(D d) : n(new Node(d)) {}
  int sz() { return n->sz; }
  void event() {
    n->expose();
    n->l = last;
    n->rev = true;
    swap(n->lsm, n->rsm);
  }
  void link(LCTree r) {
    event();
    r.n->expose();
    n->p = r.n;
  }

  void set(int x) {
    n->expose();
    n->l = last;
    n->update();
    n->updata(x);
  }
  int get() {
    n->expose();
    n->l = last;
    n->update();
    if (n->mv < 0)
      return n->mv;
    return n->ma;
  }
};
LCTree::Node LCTree::last_d = LCTree::Node((NP)NULL, NULL);
LCTree::NP LCTree::last = &last_d;

const int MN = 201000;
LCTree tr[MN];

vector<int> g[MN];
int root[MN];

int main() {
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n; i++) {
    int w;
    scanf("%d", &w);
    tr[i] = LCTree(w);
  }
  for (int i = 0; i < n - 1; i++) {
    int s, e;
    scanf("%d %d", &s, &e);
    s--;
    e--;
    g[s].push_back(e);
    g[e].push_back(s);
  }
  queue<P> qu;
  qu.push(P(0, -1));
  while (!qu.empty()) {
    int a, b;
    tie(a, b) = qu.front();
    qu.pop();
    root[a] = b;
    for (int d : g[a]) {
      if (d == b)
        continue;
      qu.push(P(d, a));
    }
  }
  for (int i = 1; i < n; i++) {
    tr[i].link(tr[root[i]]);
  }
  for (int i = 0; i < q; i++) {
    int t, a, b, c;
    scanf("%d %d %d %d", &t, &a, &b, &c);
    a--;
    b--;
    if (t == 1) {
      tr[a].event();
      tr[b].set(c);
    } else {
      tr[a].event();
      printf("%d\\n", tr[b].get());
    }
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

typedef long long ll;

struct LCTree {
  typedef int D;
  static const int INF = 1LL << 28;
  struct Node;
  typedef Node *NP;
  static Node last_d;
  static NP last;
  struct Node {
    NP p, l, r;
    int sz;
    int v, sm, lz;
    int lsm, rsm, ma, mv;
    bool rev;
    Node(D v)
        : p(NULL), l(last), r(last), sz(1), v(v), sm(v), lz(INF), rev(false),
          lsm(max(v, 0)), rsm(max(v, 0)), ma(max(v, 0)), mv(v) {}
    Node(NP l, NP r) : l(l), r(r), sz(0), mv(-INF) {}
    int pos() {
      if (p && p->l == this)
        return -1;
      if (p && p->r == this)
        return 1;
      return 0;
    }
    void rot() {
      NP q = p, qq = q->p;
      int qqp = q->pos();
      if (q->l == this) {
        q->l = r;
        r->p = q;
        r = q;
        q->p = this;
      } else {
        q->r = l;
        l->p = q;
        l = q;
        q->p = this;
      }
      q->update();
      update();
      if ((p = qq) && qqp) {
        if (qq->l == q)
          qq->l = this;
        if (qq->r == q)
          qq->r = this;
        qq->update();
      }
    }
    void splay() {
      supush();
      while (pos()) {
        if (!pos() || !p->pos()) {
          rot();
        } else if (p->pos() == pos()) {
          p->rot();
          rot();
        } else {
          rot();
          rot();
        }
      }
    }
    void expose() {
      NP u = this;
      while (u) {
        u->splay();
        u = u->p;
      }
      u = this;
      while (u->p) {
        u->p->r = u;
        u = u->p;
        u->update();
      }
      splay();
    }
    void push() {
      if (rev) {
        swap(l, r);
        if (l->sz) {
          l->rev ^= true;
          swap(l->lsm, l->rsm);
        }
        if (r->sz) {
          r->rev ^= true;
          swap(r->lsm, r->rsm);
        }
        rev = false;
      }

      if (lz != INF) {
        if (l->sz) {
          l->updata(lz);
        }
        if (r->sz) {
          r->updata(lz);
        }
        lz = INF;
      }
    }
    void supush() {
      if (pos()) {
        p->supush();
      }
      push();
    }
    void updata(D d) {
      v = d;
      sm = sz * d;
      lz = d;
      lsm = rsm = ma = max(0, sm);
      mv = lz;
    }
    NP update() {
      if (this == last)
        return this;
      sz = 1 + l->sz + r->sz;
      sm = v + l->sm + r->sm;
      lsm = max(l->lsm, l->sm + v + r->lsm);
      rsm = max(r->rsm, r->sm + v + l->rsm);
      ma = max(l->ma, r->ma);
      ma = max(ma, l->rsm + v + r->lsm);
      mv = max(l->mv, r->mv);
      mv = max(mv, v);
      return this;
    }
  } *n;
  LCTree() : n(last) {}
  LCTree(NP n) : n(n) {}
  LCTree(D d) : n(new Node(d)) {}
  int sz() { return n->sz; }
  void event() {
    n->expose();
    n->r = last;
    n->rev = true;
    swap(n->lsm, n->rsm);
  }
  void link(LCTree r) {
    n->expose();
    r.n->expose();
    n->p = r.n;
  }

  void set(int x) {
    n->expose();
    n->r = last;
    n->update();
    n->updata(x);
  }
  int get() {
    n->expose();
    n->r = last;
    n->update();
    if (n->mv < 0)
      return n->mv;
    return n->ma;
  }
};
LCTree::Node LCTree::last_d = LCTree::Node((NP)NULL, NULL);
LCTree::NP LCTree::last = &last_d;

const int MN = 201000;
LCTree tr[MN];
vector<int> g[MN];
int root[MN];
void dfs(int p, int b) {
  root[p] = b;
  for (int d : g[p]) {
    if (d == b)
      continue;
    dfs(d, p);
  }
}
int main() {
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n; i++) {
    int w;
    scanf("%d", &w);
    tr[i] = LCTree(w);
  }
  for (int i = 0; i < n - 1; i++) {
    int s, e;
    scanf("%d %d", &s, &e);
    s--;
    e--;
    g[s].push_back(e);
    g[e].push_back(s);
  }
  dfs(0, -1);
  for (int i = 1; i < n; i++) {
    tr[i].link(tr[root[i]]);
  }
  for (int i = 0; i < q; i++) {
    int t, a, b, c;
    scanf("%d %d %d %d", &t, &a, &b, &c);
    a--;
    b--;
    if (t == 1) {
      tr[a].event();
      tr[b].set(c);
    } else {
      tr[a].event();
      printf("%d\\n", tr[b].get());
    }
  }
}