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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define sgn(v) (abs((v)) < eps ? 0 : ((v) < 0 ? -1 : 1))
#define sqr(v) ((v) * (v))
#define mb make_pair
#define debug 0
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
const double eps = 1e-9;
const double pi = acos(-1);
const int maxn = 2e5 + 100;
struct Edge {
  int v, next;
} edge[maxn * 2];
int ne, head[maxn];
void add(int u, int v) {
  edge[ne].v = v;
  edge[ne].next = head[u];
  head[u] = ne++;
}
int sz[maxn], hv[maxn], dep[maxn], fa[maxn], anc[maxn], id[maxn], idx;
int w[maxn], who[maxn];
void pre_dfs(int u, int pre) {
  sz[u] = 1;
  hv[u] = 0;
  dep[u] = dep[pre] + 1;
  fa[u] = pre;
  int i, v;
  for (i = head[u]; i != -1; i = edge[i].next) {
    v = edge[i].v;
    if (v == pre)
      continue;
    pre_dfs(v, u);
    sz[u] += sz[v];
    if (sz[hv[u]] < sz[v])
      hv[u] = v;
  }
}
void pre_build(int u, int last) {
  anc[u] = last;
  id[u] = ++idx;
  who[idx] = u;
  if (hv[u])
    pre_build(hv[u], last);
  int i, v;
  for (i = head[u]; i != -1; i = edge[i].next) {
    v = edge[i].v;
    if (v == fa[u] || v == hv[u])
      continue;
    pre_build(v, v);
  }
}
int max(int a, int b, int c) {
  a = max(a, b);
  a = max(a, c);
  return a;
}
struct Node {
  int sum, lmax, rmax, mmax;
  Node() {}
  Node(int w, int len) {
    if (w >= 0)
      sum = lmax = rmax = mmax = w * len;
    else {
      sum = w * len;
      lmax = rmax = mmax = w;
    }
  }
  Node operator+(const Node &p) const {
    Node res;
    res.sum = sum + p.sum;
    res.lmax = max(lmax, sum + p.lmax);
    res.rmax = max(p.rmax, p.sum + rmax);
    res.mmax = max(mmax, p.mmax, rmax + p.lmax);
    return res;
  }
};
#define lch (id << 1)
#define rch (id << 1 | 1)
int f, ans, pre;
vector<Node> vl, vr;
const int mliv = -20000;
struct Segment {
  Node tr[maxn << 2];
  int lazy[maxn << 2];
  void build(int id, int l, int r) {
    lazy[id] = mliv;
    if (l == r)
      tr[id] = Node(w[who[l]], 1);
    else {
      int mid = (l + r) / 2;
      build(lch, l, mid);
      build(rch, mid + 1, r);
      tr[id] = tr[lch] + tr[rch];
    }
  }
  void push_down(int id, int l, int r) {
    int mid = l + r >> 1;
    int c = lazy[id];
    tr[lch] = Node(c, mid - l + 1);
    lazy[lch] = c;
    tr[rch] = Node(c, r - mid);
    lazy[rch] = c;
    lazy[id] = mliv;
  }
  void update(int id, int l, int r, int L, int R, int c) {
    if (L <= l && r <= R) {
      tr[id] = Node(c, r - l + 1);
      lazy[id] = c;
    } else {
      int mid = l + r >> 1;
      if (lazy[id] != mliv)
        push_down(id, l, r);
      if (L <= mid)
        update(lch, l, mid, L, R, c);
      if (R > mid)
        update(rch, mid + 1, r, L, R, c);
      tr[id] = tr[lch] + tr[rch];
    }
  }
  Node query(int id, int l, int r, int L, int R) {
    if (L <= l && r <= R) {
      f = max(tr[id].mmax, pre + tr[id].rmax);
      pre = max(tr[id].lmax, pre + tr[id].sum);
      ans = max(f, ans);
      ans = max(pre, ans);
      return tr[id];
    } else {
      int mid = l + r >> 1;
      if (lazy[id] != mliv)
        push_down(id, l, r);
      tr[id] = tr[lch] + tr[rch];
      if (L > mid)
        return query(rch, mid + 1, r, L, R);
      else if (R <= mid)
        return query(lch, l, mid, L, R);
      else
        return query(lch, l, mid, L, R) + query(rch, mid + 1, r, L, R);
    }
  }
} Tr;
void modify(int x, int y, int c) {
  int fx = anc[x], fy = anc[y];
  while (fx != fy) {
    if (dep[fx] < dep[fy])
      swap(fx, fy), swap(x, y);
    Tr.update(1, 1, idx, id[fx], id[x], c);
    x = fa[fx];
    fx = anc[x];
  }
  if (dep[x] < dep[y])
    swap(x, y);
  Tr.update(1, 1, idx, id[y], id[x], c);
}
const int INF = 2e9 + 100;
int query(int x, int y) {
  ans = -INF;
  int fx = anc[x], fy = anc[y], i;
  vl.clear();
  vr.clear();
  while (fx != fy) {
    if (dep[fx] < dep[fy]) // fy
    {
      // cout <<"r:"<<y<<" "<<fy<<endl;
      f = pre = 0;
      vr.push_back(Tr.query(1, 1, idx, id[fy], id[y]));
      y = fa[fy];
      fy = anc[y];
    } else {
      // cout <<"l:"<<x<<" "<<fx<<endl;
      f = pre = 0;
      vl.push_back(Tr.query(1, 1, idx, id[fx], id[x]));
      x = fa[fx];
      fx = anc[x];
    }
  }
  // cout <<"l:"<<y<<" "<<x<<endl;
  if (dep[x] < dep[y]) {
    f = pre = 0;
    vr.push_back(Tr.query(1, 1, idx, id[x], id[y]));
  } else {
    f = pre = 0;
    vl.push_back(Tr.query(1, 1, idx, id[y], id[x]));
  }
  f = pre = 0;
  for (i = 0; i < vl.size(); ++i) {
    // cout <<"l:"<<vl[i].sum<<" "<<vl[i].lmax<<" "<<vl[i].rmax<<"
    // "<<vl[i].mmax<<endl;
    f = max(vl[i].mmax, pre + vl[i].rmax);
    pre = max(vl[i].lmax, pre + vl[i].sum);
    ans = max(f, ans);
    ans = max(pre, ans);
  }
  for (i = vr.size() - 1; i >= 0; --i) {
    // cout <<"r:"<<vr[i].sum<<" "<<vr[i].lmax<<" "<<vr[i].rmax<<"
    // "<<vr[i].mmax<<endl;
    f = max(vr[i].mmax, pre + vr[i].lmax);
    pre = max(vr[i].rmax, pre + vr[i].sum);
    ans = max(f, ans);
    ans = max(pre, ans);
  }
  return ans;
}
int main() {
  int i, n, q;
  int u, v, a, b, c, t;
  scanf("%d%d", &n, &q);
  ne = 0;
  memset(head, -1, sizeof(head));
  for (i = 1; i <= n; ++i)
    scanf("%d", &w[i]);
  for (i = 1; i < n; ++i) {
    scanf("%d%d", &u, &v);
    add(u, v);
    add(v, u);
  }
  // cout <<ne<<endl;
  // cout <<"dfs"<<endl;
  pre_dfs(n / 2 + 1, 0);
  idx = 0;
  // cout <<"dfs"<<endl;
  pre_build(n / 2 + 1, n / 2 + 1);
  // for(i=1;i<=n;++i)cout <<fa[i]<<" ";cout <<endl;
  // for(i=1;i<=n;++i)cout <<hv[i]<<" ";cout <<endl;
  // for(i=1;i<=n;++i)cout <<anc[i]<<" ";cout <<endl;
  Tr.build(1, 1, idx);
  // cout <<"build"<<endl;
  for (i = 0; i < q; ++i) {
    scanf("%d%d%d%d", &t, &a, &b, &c);
    if (t == 1)
      modify(a, b, c);
    else
      printf("%d\\n", query(a, b));
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define sgn(v) (abs((v)) < eps ? 0 : ((v) < 0 ? -1 : 1))
#define sqr(v) ((v) * (v))
#define mb make_pair
#define debug 0
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
const double eps = 1e-9;
const double pi = acos(-1);
const int maxn = 2e5 + 100;
struct Edge {
  int v, next;
} edge[maxn * 2];
int ne, head[maxn];
void add(int u, int v) {
  edge[ne].v = v;
  edge[ne].next = head[u];
  head[u] = ne++;
}
int sz[maxn], hv[maxn], dep[maxn], fa[maxn], anc[maxn], id[maxn], idx;
int w[maxn], who[maxn];
void pre_dfs(int u, int pre) {
  sz[u] = 1;
  hv[u] = 0;
  dep[u] = dep[pre] + 1;
  fa[u] = pre;
  int i, v;
  for (i = head[u]; i != -1; i = edge[i].next) {
    v = edge[i].v;
    if (v == pre)
      continue;
    pre_dfs(v, u);
    sz[u] += sz[v];
    if (sz[hv[u]] < sz[v])
      hv[u] = v;
  }
}
void pre_build(int u, int last) {
  anc[u] = last;
  id[u] = ++idx;
  who[idx] = u;
  if (hv[u])
    pre_build(hv[u], last);
  int i, v;
  for (i = head[u]; i != -1; i = edge[i].next) {
    v = edge[i].v;
    if (v == fa[u] || v == hv[u])
      continue;
    pre_build(v, v);
  }
}
int max(int a, int b, int c) {
  a = max(a, b);
  a = max(a, c);
  return a;
}
struct Node {
  int sum, lmax, rmax, mmax;
  Node() {}
  Node(int w, int len) {
    if (w >= 0)
      sum = lmax = rmax = mmax = w * len;
    else {
      sum = w * len;
      lmax = rmax = mmax = w;
    }
  }
  Node operator+(const Node &p) const {
    Node res;
    res.sum = sum + p.sum;
    res.lmax = max(lmax, sum + p.lmax);
    res.rmax = max(p.rmax, p.sum + rmax);
    res.mmax = max(mmax, p.mmax, rmax + p.lmax);
    return res;
  }
};
#define lch (id << 1)
#define rch (id << 1 | 1)
int f, ans, pre;
vector<Node> vl, vr;
const int mliv = -20000;
struct Segment {
  Node tr[maxn << 2];
  int lazy[maxn << 2];
  void build(int id, int l, int r) {
    lazy[id] = mliv;
    if (l == r)
      tr[id] = Node(w[who[l]], 1);
    else {
      int mid = (l + r) / 2;
      build(lch, l, mid);
      build(rch, mid + 1, r);
      tr[id] = tr[lch] + tr[rch];
    }
  }
  void push_down(int id, int l, int r) {
    int mid = l + r >> 1;
    int c = lazy[id];
    tr[lch] = Node(c, mid - l + 1);
    lazy[lch] = c;
    tr[rch] = Node(c, r - mid);
    lazy[rch] = c;
    lazy[id] = mliv;
  }
  void update(int id, int l, int r, int L, int R, int c) {
    if (L <= l && r <= R) {
      tr[id] = Node(c, r - l + 1);
      lazy[id] = c;
    } else {
      int mid = l + r >> 1;
      if (lazy[id] != mliv)
        push_down(id, l, r);
      if (L <= mid)
        update(lch, l, mid, L, R, c);
      if (R > mid)
        update(rch, mid + 1, r, L, R, c);
      tr[id] = tr[lch] + tr[rch];
    }
  }
  Node query(int id, int l, int r, int L, int R) {
    if (L <= l && r <= R) {
      f = max(tr[id].mmax, pre + tr[id].rmax);
      pre = max(tr[id].lmax, pre + tr[id].sum);
      ans = max(f, ans);
      ans = max(pre, ans);
      return tr[id];
    } else {
      int mid = l + r >> 1;
      if (lazy[id] != mliv)
        push_down(id, l, r);
      tr[id] = tr[lch] + tr[rch];
      if (L > mid)
        return query(rch, mid + 1, r, L, R);
      else if (R <= mid)
        return query(lch, l, mid, L, R);
      else
        return query(lch, l, mid, L, R) + query(rch, mid + 1, r, L, R);
    }
  }
} Tr;
void modify(int x, int y, int c) {
  int fx = anc[x], fy = anc[y];
  while (fx != fy) {
    if (dep[fx] < dep[fy])
      swap(fx, fy), swap(x, y);
    Tr.update(1, 1, idx, id[fx], id[x], c);
    x = fa[fx];
    fx = anc[x];
  }
  if (dep[x] < dep[y])
    swap(x, y);
  Tr.update(1, 1, idx, id[y], id[x], c);
}
const int INF = 2e9 + 100;
int query(int x, int y) {
  ans = -INF;
  int fx = anc[x], fy = anc[y], i;
  vl.clear();
  vr.clear();
  while (fx != fy) {
    if (dep[fx] < dep[fy]) // fy
    {
      // cout <<"r:"<<y<<" "<<fy<<endl;
      f = pre = 0;
      vr.push_back(Tr.query(1, 1, idx, id[fy], id[y]));
      y = fa[fy];
      fy = anc[y];
    } else {
      // cout <<"l:"<<x<<" "<<fx<<endl;
      f = pre = 0;
      vl.push_back(Tr.query(1, 1, idx, id[fx], id[x]));
      x = fa[fx];
      fx = anc[x];
    }
  }
  // cout <<"l:"<<y<<" "<<x<<endl;
  if (dep[x] < dep[y]) {
    f = pre = 0;
    vr.push_back(Tr.query(1, 1, idx, id[x], id[y]));
  } else {
    f = pre = 0;
    vl.push_back(Tr.query(1, 1, idx, id[y], id[x]));
  }
  f = pre = 0;
  for (i = 0; i < vl.size(); ++i) {
    // cout <<"l:"<<vl[i].sum<<" "<<vl[i].lmax<<" "<<vl[i].rmax<<"
    // "<<vl[i].mmax<<endl;
    f = max(vl[i].mmax, pre + vl[i].rmax);
    pre = max(vl[i].lmax, pre + vl[i].sum);
    ans = max(f, ans);
    ans = max(pre, ans);
  }
  for (i = vr.size() - 1; i >= 0; --i) {
    // cout <<"r:"<<vr[i].sum<<" "<<vr[i].lmax<<" "<<vr[i].rmax<<"
    // "<<vr[i].mmax<<endl;
    f = max(vr[i].mmax, pre + vr[i].lmax);
    pre = max(vr[i].rmax, pre + vr[i].sum);
    ans = max(f, ans);
    ans = max(pre, ans);
  }
  return ans;
}
int main() {
  int i, n, q;
  int u, v, a, b, c, t;
  scanf("%d%d", &n, &q);
  ne = 0;
  memset(head, -1, sizeof(head));
  for (i = 1; i <= n; ++i)
    scanf("%d", &w[i]);
  for (i = 1; i < n; ++i) {
    scanf("%d%d", &u, &v);
    add(u, v);
    add(v, u);
  }
  pre_dfs(1, 0);
  idx = 0;
  pre_build(1, 1);
  // for(i=1;i<=n;++i)cout <<fa[i]<<" ";cout <<endl;
  // for(i=1;i<=n;++i)cout <<hv[i]<<" ";cout <<endl;
  // for(i=1;i<=n;++i)cout <<anc[i]<<" ";cout <<endl;
  Tr.build(1, 1, idx);
  for (i = 0; i < q; ++i) {
    scanf("%d%d%d%d", &t, &a, &b, &c);
    if (t == 1)
      modify(a, b, c);
    else
      printf("%d\\n", query(a, b));
  }
  return 0;
}