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

#include <bits/stdc++.h>
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
using namespace std;

typedef long long ll;
typedef tuple<int, int> tii;
typedef tuple<ll, ll, ll, ll> state;

const ll INF = 1LL << 60;

inline state vmerge(state l, state r) {
  ll ans, all, left, right;
  ll lans, lall, lleft, lright;
  tie(lans, lall, lleft, lright) = l;
  ll rans, rall, rleft, rright;
  tie(rans, rall, rleft, rright) = r;
  ans = max({lans, rans, lright + rleft});
  all = lall + rall;
  left = max(lleft, lall + rleft);
  right = max(rright, rall + lright);
  return make_tuple(ans, all, left, right);
}

template <typename T> class SegmentTree {
public:
  int n;
  SegmentTree(int size, T o) : out(o) {
    for (n = 1; n < size; n <<= 1)
      ;
    data = vector<state>(2 * n, make_tuple(out, 0, out, out));
    lazy = vector<T>(2 * n, out);
  }

  void update(int a, int b, T x, int k, int l, int r) {
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      lazy[k] = x;
      T ans = max(x, x * (r - l)), all = x * (r - l);
      T left = ans, right = ans;
      data[k] = make_tuple(ans, all, left, right);
      return;
    }
    lazy_evaluate(k, l, r);
    update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    update(a, b, x, k * 2 + 2, (l + r) / 2, r);
    data[k] = vmerge(data[k * 2 + 1], data[k * 2 + 2]);
  }

  void update(int a, int b, T x) { return update(a, b, x, 0, 0, n); }

  state query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return make_tuple(-INF, 0, -INF, -INF);
    if (a <= l && r <= b)
      return data[k];
    lazy_evaluate(k, l, r);
    state vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    state vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return vmerge(vl, vr);
  }

  state query(int a, int b) { return query(a, b, 0, 0, n); }

private:
  vector<state> data;
  vector<T> lazy;
  const T out;

  inline void lazy_evaluate(int k, int l, int r) {
    if (lazy[k] == out)
      return;
    T x = lazy[k];
    update(l, (l + r) / 2, x, k * 2 + 1, l, (l + r) / 2);
    update((l + r) / 2, r, x, k * 2 + 2, (l + r) / 2, r);
    lazy[k] = out;
  }
};

const int nmax = 200010;
vector<int> tree[nmax];
int depth[nmax], parent[nmax][20], subsize[nmax];
SegmentTree<ll> *seg[nmax];

int dfs(int v, int p, int d) {
  depth[v] = d;
  parent[v][0] = p;
  subsize[v] = 1;
  for (auto &v2 : tree[v]) {
    if (v2 == p)
      continue;
    subsize[v] += dfs(v2, v, d + 1);
  }
  return subsize[v];
}

tii lca(int u, int v) {
  for (int i = 19; i >= 0; --i)
    if ((depth[v] - depth[u]) >> i & 1)
      v = parent[v][i];
  if (u == v)
    return make_tuple(u, v);
  for (int i = 19; i >= 0; --i) {
    if (parent[u][i] != parent[v][i]) {
      u = parent[u][i];
      v = parent[v][i];
    }
  }
  return make_tuple(u, parent[u][0]);
}

struct {
  int head, pos, index, size;
} chain[nmax];

int hld(int v, int p, int &id) {
  if (chain[id].head == -1)
    chain[id].head = v;
  chain[v].index = id;
  chain[v].pos = chain[id].size;
  chain[id].size++;

  int cmax = -1, u = -1;
  for (auto &v2 : tree[v]) {
    if (v2 == p)
      continue;
    if (cmax < subsize[v2])
      cmax = subsize[v2], u = v2;
  }

  if (u >= 0)
    hld(u, v, id);

  for (auto &v2 : tree[v]) {
    if (v2 == p || v2 == u)
      continue;
    hld(v2, v, ++id);
  }
  return id + 1;
}

void fix(int a, int b, int c) {
  while (1) {
    int v = chain[chain[a].index].head;
    if (depth[v] <= depth[b])
      v = b;
    seg[chain[a].index]->update(chain[v].pos, chain[a].pos + 1, c);
    if (v == b)
      break;
    a = parent[v][0];
  }
  return;
}

state calc(int a, int b) {
  state ret = make_tuple(-INF, 0, -INF, -INF);
  while (1) {
    int v = chain[chain[a].index].head;
    if (depth[v] <= depth[b])
      v = b;
    state cur = seg[chain[a].index]->query(chain[v].pos, chain[a].pos + 1);
    ret = vmerge(cur, ret);
    if (v == b)
      break;
    a = parent[v][0];
  }
  return ret;
}

int n, q, w[nmax];

void run(void) {
  cin >> n >> q;
  rep(i, n) cin >> w[i];
  rep(i, n - 1) {
    int a, b;
    cin >> a >> b;
    tree[a - 1].push_back(b - 1);
    tree[b - 1].push_back(a - 1);
  }
  rep(i, n) chain[i].head = -1,
            chain[i].index = chain[i].pos = chain[i].size = 0;
  int chain_num = 0;
  dfs(0, -1, 0);
  int m = hld(0, -1, chain_num);

  rep(d, 19) rep(i, n) {
    if (parent[i][d] == -1)
      parent[i][d + 1] = -1;
    else
      parent[i][d + 1] = parent[parent[i][d]][d];
  }

  /*
  rep(i,n){
          cerr << "vertex: " << i << endl;
          rep(d,3) cerr << parent[i][d] << endl;
  }
  */
  rep(i, m) seg[i] = new SegmentTree<ll>(chain[i].size, -INF);
  rep(i, n) seg[chain[i].index]->update(chain[i].pos, chain[i].pos + 1, w[i]);

  rep(loop, q) {
    int t, a, b, c;
    cin >> t >> a >> b >> c;
    a--, b--;
    if (depth[a] > depth[b])
      swap(a, b);
    int u, v;
    tie(u, v) = lca(a, b);
    if (t == 1) {
      fix(a, v, c), fix(b, v, c);
    } else {
      ll ans;
      if (v == a) {
        state cur = calc(b, a);
        ans = get<0>(cur);
      } else {
        // cerr << a << " " << u << endl;
        // cerr << b << " " << v << endl;

        // cerr << parent[a][0] << " " << parent[a][1] << endl;
        state left = calc(a, u), right = calc(b, v);
        // cerr << get<2>(left) << " " << get<3>(left) << endl;
        swap(get<2>(left), get<3>(left));
        ans = get<0>(vmerge(left, right));
        // cerr << get<2>(left) << " " << get<3>(left) << endl;
      }
      cout << ans << endl;
    }
  }
  return;
}

long long esp_org, esp_new; //??????????????????
int main() {
  const int size = 128 * 1024 * 1024;
  void *p = malloc(size);
  esp_new = (long long)p + size - 1;

  __asm__("mov %%rsp, %0" : "=r"(esp_org) : :);
  __asm__("mov %0, %%rsp" : : "r"(esp_new) :);

  run();

  __asm__("mov %0, %%rsp" : : "r"(esp_org) :);
  free(p);
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
using namespace std;

typedef long long ll;
typedef tuple<int, int> tii;
typedef tuple<ll, ll, ll, ll> state;

const ll INF = 1LL << 60;

inline state vmerge(state l, state r) {
  ll ans, all, left, right;
  ll lans, lall, lleft, lright;
  tie(lans, lall, lleft, lright) = l;
  ll rans, rall, rleft, rright;
  tie(rans, rall, rleft, rright) = r;
  ans = max({lans, rans, lright + rleft});
  all = lall + rall;
  left = max(lleft, lall + rleft);
  right = max(rright, rall + lright);
  return make_tuple(ans, all, left, right);
}

template <typename T> class SegmentTree {
public:
  int n;
  SegmentTree(int size, T o) : out(o) {
    for (n = 1; n < size; n <<= 1)
      ;
    data = vector<state>(2 * n, make_tuple(out, 0, out, out));
    lazy = vector<T>(2 * n, out);
  }

  void update(int a, int b, T x, int k, int l, int r) {
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      lazy[k] = x;
      T ans = max(x, x * (r - l)), all = x * (r - l);
      T left = ans, right = ans;
      data[k] = make_tuple(ans, all, left, right);
      return;
    }
    lazy_evaluate(k, l, r);
    update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    update(a, b, x, k * 2 + 2, (l + r) / 2, r);
    data[k] = vmerge(data[k * 2 + 1], data[k * 2 + 2]);
  }

  void update(int a, int b, T x) { return update(a, b, x, 0, 0, n); }

  state query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return make_tuple(-INF, 0, -INF, -INF);
    if (a <= l && r <= b)
      return data[k];
    lazy_evaluate(k, l, r);
    state vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    state vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return vmerge(vl, vr);
  }

  state query(int a, int b) { return query(a, b, 0, 0, n); }

private:
  vector<state> data;
  vector<T> lazy;
  const T out;

  inline void lazy_evaluate(int k, int l, int r) {
    if (lazy[k] == out)
      return;
    T x = lazy[k];
    update(l, (l + r) / 2, x, k * 2 + 1, l, (l + r) / 2);
    update((l + r) / 2, r, x, k * 2 + 2, (l + r) / 2, r);
    lazy[k] = out;
  }
};

const int nmax = 200010;
vector<int> tree[nmax];
int depth[nmax], parent[nmax][20], subsize[nmax];
SegmentTree<ll> *seg[nmax];

int dfs(int v, int p, int d) {
  depth[v] = d;
  parent[v][0] = p;
  subsize[v] = 1;
  for (auto &v2 : tree[v]) {
    if (v2 == p)
      continue;
    subsize[v] += dfs(v2, v, d + 1);
  }
  return subsize[v];
}

tii lca(int u, int v) {
  for (int i = 19; i >= 0; --i)
    if ((depth[v] - depth[u]) >> i & 1)
      v = parent[v][i];
  if (u == v)
    return make_tuple(u, v);
  for (int i = 19; i >= 0; --i) {
    if (parent[u][i] != parent[v][i]) {
      u = parent[u][i];
      v = parent[v][i];
    }
  }
  return make_tuple(u, parent[u][0]);
}

struct {
  int head, pos, index, size;
} chain[nmax];

int hld(int v, int p, int &id) {
  if (chain[id].head == -1)
    chain[id].head = v;
  chain[v].index = id;
  chain[v].pos = chain[id].size;
  chain[id].size++;

  int cmax = -1, u = -1;
  for (auto &v2 : tree[v]) {
    if (v2 == p)
      continue;
    if (cmax < subsize[v2])
      cmax = subsize[v2], u = v2;
  }

  if (u >= 0)
    hld(u, v, id);

  for (auto &v2 : tree[v]) {
    if (v2 == p || v2 == u)
      continue;
    hld(v2, v, ++id);
  }
  return id + 1;
}

void fix(int a, int b, int c) {
  while (1) {
    int v = chain[chain[a].index].head;
    if (depth[v] <= depth[b])
      v = b;
    seg[chain[a].index]->update(chain[v].pos, chain[a].pos + 1, c);
    if (v == b)
      break;
    a = parent[v][0];
  }
  return;
}

state calc(int a, int b) {
  state ret = make_tuple(-INF, 0, -INF, -INF);
  while (1) {
    int v = chain[chain[a].index].head;
    if (depth[v] <= depth[b])
      v = b;
    state cur = seg[chain[a].index]->query(chain[v].pos, chain[a].pos + 1);
    ret = vmerge(cur, ret);
    if (v == b)
      break;
    a = parent[v][0];
  }
  return ret;
}

int n, q, w[200010];

int main(void) {
  cin >> n >> q;
  rep(i, n) cin >> w[i];
  rep(i, n - 1) {
    int a, b;
    cin >> a >> b;
    tree[a - 1].push_back(b - 1);
    tree[b - 1].push_back(a - 1);
  }
  rep(i, n) chain[i].head = -1,
            chain[i].index = chain[i].pos = chain[i].size = 0;
  int chain_num = 0;
  dfs(0, -1, 0);
  int m = hld(0, -1, chain_num);

  rep(d, 19) rep(i, n) {
    if (parent[i][d] == -1)
      parent[i][d + 1] = -1;
    else
      parent[i][d + 1] = parent[parent[i][d]][d];
  }

  /*
  rep(i,n){
          cerr << "vertex: " << i << endl;
          rep(d,3) cerr << parent[i][d] << endl;
  }
  */
  rep(i, m) seg[i] = new SegmentTree<ll>(chain[i].size, -INF);
  rep(i, n) seg[chain[i].index]->update(chain[i].pos, chain[i].pos + 1, w[i]);

  rep(loop, q) {
    int t, a, b, c;
    cin >> t >> a >> b >> c;
    a--, b--;
    if (depth[a] > depth[b])
      swap(a, b);
    int u, v;
    tie(u, v) = lca(a, b);
    if (t == 1) {
      fix(a, v, c), fix(b, v, c);
    } else {
      ll ans;
      if (v == a) {
        state cur = calc(b, a);
        ans = get<0>(cur);
      } else {
        // cerr << a << " " << u << endl;
        // cerr << b << " " << v << endl;

        // cerr << parent[a][0] << " " << parent[a][1] << endl;
        state left = calc(a, u), right = calc(b, v);
        // cerr << get<2>(left) << " " << get<3>(left) << endl;
        swap(get<2>(left), get<3>(left));
        ans = get<0>(vmerge(left, right));
        // cerr << get<2>(left) << " " << get<3>(left) << endl;
      }
      cout << ans << endl;
    }
  }
  return 0;
}