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

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int> vint;
typedef pair<int, int> pint;
typedef vector<pint> vpint;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, f, n) for (int i = (f); i < (n); i++)
#define all(v) (v).begin(), (v).end()
#define each(it, v)                                                            \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
#define pb push_back
#define fi first
#define se second
template <typename A, typename B> inline void chmin(A &a, B b) {
  if (a > b)
    a = b;
}
template <typename A, typename B> inline void chmax(A &a, B b) {
  if (a < b)
    a = b;
}

const int INF = 1001001001001001001ll;

struct node {
  int v, l, r, s;
  node(int a) { v = l = r = s = a; }
  node(int v, int l, int r, int s) : v(v), l(l), r(r), s(s) {}
  node() {
    v = l = r = -INF;
    s = 0;
  }
};
node operator+(const node &a, const node &b) {
  node c;
  c.v = max(max(a.v, b.v), a.r + b.l);
  c.s = a.s + b.s;
  c.l = max(a.l, a.s + b.l);
  c.r = max(b.r, b.s + a.r);
  return c;
}

struct segtree {
  static const int SEG = 1 << 18;
  vint put;
  vector<node> dat;
  segtree() : put(SEG * 2, INF), dat(SEG * 2) {}

  inline void push(int k, int l, int r) {
    if (put[k] == INF)
      return;
    if (put[k] >= 0)
      dat[k] = node(put[k] * (r - l));
    else
      dat[k] = node(put[k], put[k], put[k], put[k] * (r - l));

    if (k < SEG - 1) {
      put[k * 2 + 1] = put[k];
      put[k * 2 + 2] = put[k];
    }
    put[k] = INF;
  }

  void update(int a, int b, int x, int k = 0, int l = 0, int r = SEG) {
    push(k, l, r);
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      put[k] = x;
      push(k, l, r);
      return;
    }
    update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    update(a, b, x, k * 2 + 2, (l + r) / 2, r);
    dat[k] = dat[k * 2 + 1] + dat[k * 2 + 2];
  }
  node query(int a, int b, int k = 0, int l = 0, int r = SEG) {
    push(k, l, r);
    if (r <= a || b <= l)
      return node();
    if (a <= l && r <= b)
      return dat[k];
    return query(a, b, k * 2 + 1, l, (l + r) / 2) +
           query(a, b, k * 2 + 2, (l + r) / 2, r);
  }
};

const int SIZE = 222222;

int N, Q;
int W[SIZE];
vint G[SIZE];

int par[SIZE], dep[SIZE], hev[SIZE], pos[SIZE], head[SIZE], sz[SIZE];
segtree seg;

void dfs() {
  vint vs = {0};
  par[0] = -1;
  dep[0] = 0;
  rep(i, N) {
    int v = vs[i];
    for (auto u : G[v]) {
      if (u == par[v])
        continue;
      par[u] = v;
      dep[u] = dep[v] + 1;
      vs.pb(u);
    }
  }

  for (int i = vs.size() - 1; i >= 0; i--) {
    int v = vs[i];
    sz[v] = 1;
    hev[v] = -1;
    int ma = 0;
    for (auto u : G[v]) {
      if (u == par[v])
        continue;
      if (ma < sz[u]) {
        ma = sz[u];
        hev[v] = u;
      }
      sz[v] += sz[u];
    }
  }
  /*
  par[v]=p;
  dep[v]=d;
  hev[v]=-1;
  int ma=0,sum=1;
  rep(i,G[v].size()){
      int to=G[v][i];
      if(to==p)continue;
      int tmp=dfs(to,v,d+1);
      if(ma<tmp){
          ma=tmp;
          hev[v]=to;
      }
      sum+=tmp;
  }
  return sum;
  */
}

void init() {
  dfs();
  int idx = 0;
  rep(i, N) {
    if (~par[i] && hev[par[i]] == i)
      continue;
    for (int j = i; ~j; j = hev[j]) {
      head[j] = i;
      pos[j] = idx++;
    }
  }
  rep(i, N) { seg.update(pos[i], pos[i] + 1, W[i]); }
}

void query1(int a, int b, int c) {
  while (head[a] != head[b]) {
    if (dep[head[a]] < dep[head[b]])
      swap(a, b);
    seg.update(pos[head[a]], pos[a] + 1, c);
    a = par[head[a]];
  }
  if (dep[a] > dep[b])
    swap(a, b);
  seg.update(pos[a], pos[b] + 1, c);
}

int query2(int a, int b) {
  node x, y;
  while (head[a] != head[b]) {
    if (dep[head[a]] >= dep[head[b]]) {
      x = seg.query(pos[head[a]], pos[a] + 1) + x;
      a = par[head[a]];
    } else {
      y = seg.query(pos[head[b]], pos[b] + 1) + y;
      b = par[head[b]];
    }
  }

  if (dep[a] >= dep[b]) {
    x = seg.query(pos[b], pos[a] + 1) + x;
  } else {
    y = seg.query(pos[a], pos[b] + 1) + y;
  }

  swap(x.l, x.r);
  x = x + y;
  return x.v;
}

signed main() {
  scanf("%lld%lld", &N, &Q);
  rep(i, N) scanf("%lld", &W[i]);

  rep(i, N - 1) {
    int a, b;
    scanf("%lld%lld", &a, &b);
    a--;
    b--;
    G[a].pb(b);
    G[b].pb(a);
  }
  init();

  while (Q--) {
    int t, a, b, c;
    scanf("%lld%lld%lld%lld", &t, &a, &b, &c);
    a--;
    b--;
    if (t == 1) {
      query1(a, b, c);
    } else {
      printf("%lld\\n", query2(a, b));
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int> vint;
typedef pair<int, int> pint;
typedef vector<pint> vpint;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, f, n) for (int i = (f); i < (n); i++)
#define all(v) (v).begin(), (v).end()
#define each(it, v)                                                            \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
#define pb push_back
#define fi first
#define se second
template <typename A, typename B> inline void chmin(A &a, B b) {
  if (a > b)
    a = b;
}
template <typename A, typename B> inline void chmax(A &a, B b) {
  if (a < b)
    a = b;
}

const int INF = 1001001001001001001ll;

struct node {
  int v, l, r, s;
  node(int a) { v = l = r = s = a; }
  node(int v, int l, int r, int s) : v(v), l(l), r(r), s(s) {}
  node() {
    v = l = r = -INF;
    s = 0;
  }
};
node operator+(const node &a, const node &b) {
  node c;
  c.v = max(max(a.v, b.v), a.r + b.l);
  c.s = a.s + b.s;
  c.l = max(a.l, a.s + b.l);
  c.r = max(b.r, b.s + a.r);
  return c;
}

struct segtree {
  static const int SEG = 1 << 18;
  vint put;
  vector<node> dat;
  segtree() : put(SEG * 2, INF), dat(SEG * 2) {}

  inline void push(int k, int l, int r) {
    if (put[k] == INF)
      return;
    if (put[k] >= 0)
      dat[k] = node(put[k] * (r - l));
    else
      dat[k] = node(put[k], put[k], put[k], put[k] * (r - l));

    if (k < SEG - 1) {
      put[k * 2 + 1] = put[k];
      put[k * 2 + 2] = put[k];
    }
    put[k] = INF;
  }

  void update(int a, int b, int x, int k = 0, int l = 0, int r = SEG) {
    push(k, l, r);
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      put[k] = x;
      push(k, l, r);
      return;
    }
    update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    update(a, b, x, k * 2 + 2, (l + r) / 2, r);
    dat[k] = dat[k * 2 + 1] + dat[k * 2 + 2];
  }
  node query(int a, int b, int k = 0, int l = 0, int r = SEG) {
    push(k, l, r);
    if (r <= a || b <= l)
      return node();
    if (a <= l && r <= b)
      return dat[k];
    return query(a, b, k * 2 + 1, l, (l + r) / 2) +
           query(a, b, k * 2 + 2, (l + r) / 2, r);
  }
};

const int SIZE = 222222;

int N, Q;
int W[SIZE];
vint G[SIZE];

int par[SIZE], dep[SIZE], hev[SIZE], pos[SIZE], head[SIZE];
segtree seg;

int dfs(int v, int p, int d) {
  par[v] = p;
  dep[v] = d;
  hev[v] = -1;
  int ma = 0, sum = 1;
  rep(i, G[v].size()) {
    int to = G[v][i];
    if (to == p)
      continue;
    int tmp = dfs(to, v, d + 1);
    if (ma < tmp) {
      ma = tmp;
      hev[v] = to;
    }
    sum += tmp;
  }
  return sum;
}

void init() {
  dfs(0, -1, 0);
  int idx = 0;
  rep(i, N) {
    if (~par[i] && hev[par[i]] == i)
      continue;
    for (int j = i; ~j; j = hev[j]) {
      head[j] = i;
      pos[j] = idx++;
    }
  }
  rep(i, N) { seg.update(pos[i], pos[i] + 1, W[i]); }
}

void query1(int a, int b, int c) {
  while (head[a] != head[b]) {
    if (dep[head[a]] < dep[head[b]])
      swap(a, b);
    seg.update(pos[head[a]], pos[a] + 1, c);
    a = par[head[a]];
  }
  if (dep[a] > dep[b])
    swap(a, b);
  seg.update(pos[a], pos[b] + 1, c);
}

int query2(int a, int b) {
  node x, y;
  while (head[a] != head[b]) {
    if (dep[head[a]] >= dep[head[b]]) {
      x = seg.query(pos[head[a]], pos[a] + 1) + x;
      a = par[head[a]];
    } else {
      y = seg.query(pos[head[b]], pos[b] + 1) + y;
      b = par[head[b]];
    }
  }

  if (dep[a] >= dep[b]) {
    x = seg.query(pos[b], pos[a] + 1) + x;
  } else {
    y = seg.query(pos[a], pos[b] + 1) + y;
  }

  swap(x.l, x.r);
  x = x + y;
  return x.v;
}

signed main() {
  scanf("%lld%lld", &N, &Q);
  rep(i, N) scanf("%lld", &W[i]);

  rep(i, N - 1) {
    int a, b;
    scanf("%lld%lld", &a, &b);
    a--;
    b--;
    G[a].pb(b);
    G[b].pb(a);
  }
  init();

  while (Q--) {
    int t, a, b, c;
    scanf("%lld%lld%lld%lld", &t, &a, &b, &c);
    a--;
    b--;
    if (t == 1) {
      query1(a, b, c);
    } else {
      printf("%lld\\n", query2(a, b));
    }
  }
  return 0;
}