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

#pragma comment(linker, "/STACK:102400000,102400000")
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
const int N = 200010;
const int inf = 0x3f3f3f3f;
struct edge {
  int to, next;
  edge() {}
  edge(int to, int next) : to(to), next(next) {}
} e[N << 1];
int head[N], tot;
int top[N], a[N], b[N];
int fa[N], dep[N], num[N], p[N], fp[N], son[N], pos;
void init() {
  memset(head, -1, sizeof head);
  tot = 0;
  pos = 0;
  memset(son, 0, sizeof son);
}
void addedge(int u, int v) {
  e[tot] = edge(v, head[u]);
  head[u] = tot++;
}
// void dfs1(int u,int pre,int d)
//{
//     dep[u]=d;
//     fa[u]=pre;num[u]=1;
//     for(int i=head[u];~i;i=e[i].next)
//     {
//         int v=e[i].to;
//         if(v==pre)continue;
//         dfs1(v,u,d+1);
//         num[u]+=num[v];
//         if(son[u]==0||num[v]>num[son[u]])son[u]=v;
//     }
// }
// void getpos(int u,int sp)
//{
//     top[u]=sp;
//     p[u]=++pos;
//     fp[p[u]]=u;
//     if(son[u]==0)return;
//     getpos(son[u],sp);
//     for(int i=head[u];~i;i=e[i].next)
//     {
//         int v=e[i].to;
//         if(v!=son[u]&&v!=fa[u])
//         getpos(v,v);
//     }
// }

struct node {
  int lsum, rsum, msum, sum;
  void sp() { swap(lsum, rsum); }
} s[N << 2];
int col[N << 2];
node calc(node a, node b) {
  node c;
  c.sum = a.sum + b.sum;
  c.msum = max(a.msum, b.msum);
  c.lsum = max(a.lsum, a.sum + b.sum);
  c.rsum = max(b.rsum, a.sum + b.sum);
  c.lsum = max(c.lsum, a.sum + b.lsum);
  c.rsum = max(c.rsum, b.sum + a.rsum);
  c.msum = max(c.msum, max(c.lsum, c.rsum));
  c.msum = max(c.msum, a.rsum + b.lsum);
  return c;
}
void pushup(int rt) { s[rt] = calc(s[rt << 1], s[rt << 1 | 1]); }
void build(int l, int r, int rt) {
  col[rt] = inf;
  if (l == r) {
    s[rt].lsum = s[rt].rsum = s[rt].msum = s[rt].sum = b[l];
    return;
  }
  int m = (l + r) >> 1;
  build(lson);
  build(rson);
  pushup(rt);
}
void pushdown(int rt, int len) {
  if (col[rt] != inf) {
    col[rt << 1] = col[rt << 1 | 1] = col[rt];
    s[rt << 1].sum = col[rt] * (len - (len >> 1));
    s[rt << 1 | 1].sum = col[rt] * (len >> 1);
    if (col[rt] > 0) {
      s[rt << 1].lsum = s[rt << 1].rsum = s[rt << 1].msum =
          col[rt] * (len - (len >> 1));
      s[rt << 1 | 1].lsum = s[rt << 1 | 1].rsum = s[rt << 1 | 1].msum =
          col[rt] * (len >> 1);
    } else {
      s[rt << 1].lsum = s[rt << 1].rsum = s[rt << 1].msum = col[rt];
      s[rt << 1 | 1].lsum = s[rt << 1 | 1].rsum = s[rt << 1 | 1].msum = col[rt];
    }
    col[rt] = inf;
  }
}
void update(int L, int R, int c, int l, int r, int rt) {
  if (L == l && r == R) {
    col[rt] = c;
    s[rt].sum = col[rt] * (r - l + 1);
    if (col[rt] > 0) {
      s[rt].lsum = s[rt].rsum = s[rt].msum = col[rt] * (r - l + 1);
    } else {
      s[rt].lsum = s[rt].rsum = s[rt].msum = col[rt];
    }
    return;
  }
  pushdown(rt, r - l + 1);
  int m = (l + r) >> 1;
  if (R <= m)
    update(L, R, c, lson);
  else if (L > m)
    update(L, R, c, rson);
  else {
    update(L, m, c, lson);
    update(m + 1, R, c, rson);
  }
  pushup(rt);
}
void change(int u, int v, int c) {
  int f1 = top[u], f2 = top[v];
  while (f1 != f2) {
    if (dep[f1] < dep[f2]) {
      swap(f1, f2);
      swap(u, v);
    }
    update(p[f1], p[u], c, 1, pos, 1);
    u = fa[f1];
    f1 = top[u];
  }
  if (dep[u] > dep[v])
    swap(u, v);
  update(p[u], p[v], c, 1, pos, 1);
}
node query(int L, int R, int l, int r, int rt) {
  if (L == l && r == R)
    return s[rt];
  pushdown(rt, r - l + 1);
  int m = (l + r) >> 1;
  if (R <= m)
    return query(L, R, lson);
  else if (L > m)
    return query(L, R, rson);
  else {
    node a = query(L, m, lson);
    node b = query(m + 1, R, rson);
    return calc(a, b);
  }
}
node lca(int u, int v) {
  int f1 = top[u], f2 = top[v], first1 = 1, first2 = 1;
  node tmp1, tmp2, tmp;
  while (f1 != f2) {
    if (dep[f1] < dep[f2]) {
      if (first2) {
        tmp2 = query(p[f2], p[v], 1, pos, 1);
        first2 = 0;
      } else {
        tmp2 = calc(query(p[f2], p[v], 1, pos, 1), tmp2);
      }
      v = fa[f2];
      f2 = top[v];
    } else {
      if (first1) {
        tmp1 = query(p[f1], p[u], 1, pos, 1);
        tmp1.sp();
        first1 = 0;
      } else {
        tmp = query(p[f1], p[u], 1, pos, 1);
        tmp.sp();
        tmp1 = calc(tmp1, tmp);
      }
      u = fa[f1];
      f1 = top[u];
    }
  }

  if (dep[u] > dep[v]) {
    if (first1) {
      tmp1 = query(p[v], p[u], 1, pos, 1);
      tmp1.sp();
      first1 = 0;
    } else {
      tmp = query(p[v], p[u], 1, pos, 1);
      tmp.sp();
      tmp1 = calc(tmp1, tmp);
    }
  } else {
    if (first2) {
      tmp2 = query(p[u], p[v], 1, pos, 1);
      first2 = 0;
    } else
      tmp2 = calc(query(p[u], p[v], 1, pos, 1), tmp2);
  }
  if (first1 && !first2) {
    return tmp2;
  } else if (!first1 && first2)
    return tmp1;
  else {
    return calc(tmp1, tmp2);
  }
}
int que[N * 2], iii[N];

vector<int> G[N];
void buildlist(int n) {
  int ft = 0, rear = 0;
  que[rear++] = 1;
  fa[1] = 0;
  dep[1] = 1;
  while (ft < rear) {
    int u = que[ft++];
    for (int i = 0; i < G[u].size(); i++) {
      int v = G[u][i];
      if (v == fa[u])
        continue;
      fa[v] = u;
      que[rear++] = v;
      dep[v] = dep[u] + 1;
    }
  }
  memset(num, 0, sizeof(num));
  for (int i = n - 1; i >= 0; i--) {
    int u = que[i];
    num[u]++;
    num[fa[u]] += num[u];
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j < G[i].size(); j++)
      if (G[i][j] != fa[i])
        if (G[i][0] == fa[i] || num[G[i][j]] > num[G[i][0]])
          swap(G[i][0], G[i][j]);
  }
  top[1] = 1;
  for (int i = 1; i < n; i++) {
    int u = que[i];
    if (G[fa[u]][0] == u)
      top[u] = top[fa[u]];
    else
      top[u] = u;
  }
  memset(iii, 0, sizeof(iii));
  ft = 0;
  que[++ft] = 1;
  p[1] = ++pos;
  b[1] = a[1];
  while (ft) {
    int u = que[ft];
    if (iii[u] >= G[u].size())
      ft--;
    else if (G[u][iii[u]] == fa[u])
      iii[u]++;
    else {
      int v = G[u][iii[u]];
      que[++ft] = v;
      p[v] = ++pos;
      b[p[v]] = a[v];
      iii[u]++;
    }
  }
  //  for(int i = 1 ; i <= n ; ++ i) updata(i , i , b[i] , 1, pos, 1);
}
int main() {
  int n, q;
  while (scanf("%d%d", &n, &q) > 0) {
    for (int i = 1; i <= n; i++)
      scanf("%d", &a[i]), G[i].clear();
    init();
    for (int i = 1; i < n; i++) {
      int u, v;
      scanf("%d%d", &u, &v);
      addedge(u, v);
      addedge(v, u);
      G[u].push_back(v);
      G[v].push_back(u);
    }
    //   dfs1(1,0,0);
    //  getpos(1,1);
    buildlist(n);
    build(1, pos, 1);
    while (q--) {
      int op, a, b, c;
      scanf("%d%d%d%d", &op, &a, &b, &c);
      if (op == 1) {
        change(a, b, c);
      } else {
        node temp = lca(a, b);
        printf("%d\\n", temp.msum);
      }
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#pragma comment(linker, "/STACK:102400000,102400000")
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
const int N = 200010;
const int inf = 0x3f3f3f3f;
struct edge {
  int to, next;
  edge() {}
  edge(int to, int next) : to(to), next(next) {}
} e[N << 1];
int head[N], tot;
int top[N], a[N];
int fa[N], dep[N], num[N], p[N], fp[N], son[N], pos;
void init() {
  memset(head, -1, sizeof head);
  tot = 0;
  pos = 0;
  memset(son, 0, sizeof son);
}
void addedge(int u, int v) {
  e[tot] = edge(v, head[u]);
  head[u] = tot++;
}
void dfs1(int u, int pre, int d) {
  dep[u] = d;
  fa[u] = pre;
  num[u] = 1;
  for (int i = head[u]; ~i; i = e[i].next) {
    int v = e[i].to;
    if (v == pre)
      continue;
    dfs1(v, u, d + 1);
    num[u] += num[v];
    if (son[u] == 0 || num[v] > num[son[u]])
      son[u] = v;
  }
}
void getpos(int u, int sp) {
  top[u] = sp;
  p[u] = ++pos;
  fp[p[u]] = u;
  if (son[u] == 0)
    return;
  getpos(son[u], sp);
  for (int i = head[u]; ~i; i = e[i].next) {
    int v = e[i].to;
    if (v != son[u] && v != fa[u])
      getpos(v, v);
  }
}
struct node {
  int lsum, rsum, msum, sum;
  void sp() { swap(lsum, rsum); }
} s[N << 2];
int col[N << 2];
node calc(node a, node b) {
  node c;
  c.sum = a.sum + b.sum;
  c.msum = max(a.msum, b.msum);
  c.lsum = max(a.lsum, a.sum + b.sum);
  c.rsum = max(b.rsum, a.sum + b.sum);
  c.lsum = max(c.lsum, a.sum + b.lsum);
  c.rsum = max(c.rsum, b.sum + a.rsum);
  c.msum = max(c.msum, max(c.lsum, c.rsum));
  c.msum = max(c.msum, a.rsum + b.lsum);
  return c;
}
void pushup(int rt) { s[rt] = calc(s[rt << 1], s[rt << 1 | 1]); }
void build(int l, int r, int rt) {
  col[rt] = inf;
  if (l == r) {
    s[rt].lsum = s[rt].rsum = s[rt].msum = s[rt].sum = a[fp[l]];
    return;
  }
  int m = (l + r) >> 1;
  build(lson);
  build(rson);
  pushup(rt);
}
void pushdown(int rt, int len) {
  if (col[rt] != inf) {
    col[rt << 1] = col[rt << 1 | 1] = col[rt];
    s[rt << 1].sum = col[rt] * (len - (len >> 1));
    s[rt << 1 | 1].sum = col[rt] * (len >> 1);
    if (col[rt] > 0) {
      s[rt << 1].lsum = s[rt << 1].rsum = s[rt << 1].msum =
          col[rt] * (len - (len >> 1));
      s[rt << 1 | 1].lsum = s[rt << 1 | 1].rsum = s[rt << 1 | 1].msum =
          col[rt] * (len >> 1);
    } else {
      s[rt << 1].lsum = s[rt << 1].rsum = s[rt << 1].msum = col[rt];
      s[rt << 1 | 1].lsum = s[rt << 1 | 1].rsum = s[rt << 1 | 1].msum = col[rt];
    }
    col[rt] = inf;
  }
}
void update(int L, int R, int c, int l, int r, int rt) {
  if (L == l && r == R) {
    col[rt] = c;
    s[rt].sum = col[rt] * (r - l + 1);
    if (col[rt] > 0) {
      s[rt].lsum = s[rt].rsum = s[rt].msum = col[rt] * (r - l + 1);
    } else {
      s[rt].lsum = s[rt].rsum = s[rt].msum = col[rt];
    }
    return;
  }
  pushdown(rt, r - l + 1);
  int m = (l + r) >> 1;
  if (R <= m)
    update(L, R, c, lson);
  else if (L > m)
    update(L, R, c, rson);
  else {
    update(L, m, c, lson);
    update(m + 1, R, c, rson);
  }
  pushup(rt);
}
void change(int u, int v, int c) {
  int f1 = top[u], f2 = top[v];
  while (f1 != f2) {
    if (dep[f1] < dep[f2]) {
      swap(f1, f2);
      swap(u, v);
    }
    update(p[f1], p[u], c, 1, pos, 1);
    u = fa[f1];
    f1 = top[u];
  }
  if (dep[u] > dep[v])
    swap(u, v);
  update(p[u], p[v], c, 1, pos, 1);
}
node query(int L, int R, int l, int r, int rt) {
  if (L == l && r == R)
    return s[rt];
  pushdown(rt, r - l + 1);
  int m = (l + r) >> 1;
  if (R <= m)
    return query(L, R, lson);
  else if (L > m)
    return query(L, R, rson);
  else {
    node a = query(L, m, lson);
    node b = query(m + 1, R, rson);
    return calc(a, b);
  }
}
node lca(int u, int v) {
  int f1 = top[u], f2 = top[v], first1 = 1, first2 = 1;
  node tmp1, tmp2, tmp;
  while (f1 != f2) {
    if (dep[f1] < dep[f2]) {
      if (first2) {
        tmp2 = query(p[f2], p[v], 1, pos, 1);
        first2 = 0;
      } else {
        tmp2 = calc(query(p[f2], p[v], 1, pos, 1), tmp2);
      }
      v = fa[f2];
      f2 = top[v];
    } else {
      if (first1) {
        tmp1 = query(p[f1], p[u], 1, pos, 1);
        tmp1.sp();
        first1 = 0;
      } else {
        tmp = query(p[f1], p[u], 1, pos, 1);
        tmp.sp();
        tmp1 = calc(tmp1, tmp);
      }
      u = fa[f1];
      f1 = top[u];
    }
  }

  if (dep[u] > dep[v]) {
    if (first1) {
      tmp1 = query(p[v], p[u], 1, pos, 1);
      tmp1.sp();
      first1 = 0;
    } else {
      tmp = query(p[v], p[u], 1, pos, 1);
      tmp.sp();
      tmp1 = calc(tmp1, tmp);
    }
  } else {
    if (first2) {
      tmp2 = query(p[u], p[v], 1, pos, 1);
      first2 = 0;
    } else
      tmp2 = calc(query(p[u], p[v], 1, pos, 1), tmp2);
  }
  if (first1 && !first2) {
    return tmp2;
  } else if (!first1 && first2)
    return tmp1;
  else {
    return calc(tmp1, tmp2);
  }
}
int main() {
  int n, q;
  while (scanf("%d%d", &n, &q) > 0) {
    for (int i = 1; i <= n; i++)
      scanf("%d", &a[i]);
    init();
    for (int i = 1; i < n; i++) {
      int u, v;
      scanf("%d%d", &u, &v);
      addedge(u, v);
      addedge(v, u);
    }
    dfs1(1, 0, 0);
    getpos(1, 1);
    build(1, pos, 1);
    while (q--) {
      int op, a, b, c;
      scanf("%d%d%d%d", &op, &a, &b, &c);
      if (op == 1) {
        change(a, b, c);
      } else {
        node temp = lca(a, b);
        printf("%d\\n", temp.msum);
      }
    }
  }
  return 0;
}