Problem p03519 (C++)

Buggy submission (status: Runtime Error):
#include "bits/stdc++.h"

using namespace std;

using ll = long long;
using P = pair<ll, ll>;

struct Query {
  using type = P;
  static type id() { return P(0, -1e15); }
  static type op(const type &l, const type &r) {
    return P(max(l.first + r.first, l.second + r.second),
             max(l.first + r.second, l.second + r.first));
  }
};

template <typename M> class SegmentTree {
  using T = typename M::type;
  int n;
  std::vector<T> node;

public:
  // v を基に初期化
  SegmentTree(const std::vector<T> &v) {
    // n は v.size() 以上の最小の2冪
    n = 1;
    while (n < int(v.size()))
      n *= 2;
    node.resize(2 * n - 1, M::id());

    // i の子 -> 2*i+1, 2*i+2 , 親 -> (i-1)/2
    for (int i = 0; i < int(v.size()); i++)
      node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = M::op(node[2 * i + 1], node[2 * i + 2]);
  }
  // Monoid::id 初期化
  SegmentTree(int _n) {
    // n は v.size() 以上の最小の2冪
    n = 1;
    while (n < _n)
      n *= 2;
    node.resize(2 * n - 1, M::id());
  }
  // x 番目を val に更新
  void update(int x, T val) {
    x += n - 1;
    node[x] = val;
    while (x > 0) {
      x = (x - 1) / 2;
      node[x] = M::op(node[2 * x + 1], node[2 * x + 2]);
    }
  }
  // v[x] を M::op(v[x], val) に更新
  void add(int x, T val) {
    x += n - 1;
    node[x] = M::op(node[x], val);
    while (x > 0) {
      x = (x - 1) / 2;
      node[x] = M::op(node[2 * x + 1], node[2 * x + 2]);
    }
  }
  // [a, b) の op
  // k := 今居るノード
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return M::id();
    if (a <= l && r <= b)
      return node[k];

    T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return M::op(vl, vr);
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, q;
  cin >> n >> q;
  assert(n * q <= 100000);
  vector<ll> a(2 * n), b(2 * n);
  vector<P> v;
  for (int i = 0; i < 2 * n; i++)
    cin >> a[i];
  for (int i = 0; i < 2 * n; i++) {
    cin >> b[i];
    v.emplace_back(P(a[i], b[i]));
  }
  SegmentTree<Query> st(v);
  while (q--) {
    ll p, x, y;
    cin >> p >> x >> y;
    p--;
    a[p] = x;
    b[p] = y;
    st.update(p, P(x, y));
    ll ret = a[0] + a[2 * n - 1] + st.query(1, 2 * n - 1).first;
    cout << ret << endl;
  }
}


Fixed submission:
#include "bits/stdc++.h"

using namespace std;

using ll = long long;
using P = pair<ll, ll>;

struct Query {
  using type = P;
  static type id() { return P(0, -1e15); }
  static type op(const type &l, const type &r) {
    return P(max(l.first + r.first, l.second + r.second),
             max(l.first + r.second, l.second + r.first));
  }
};

template <typename M> class SegmentTree {
  using T = typename M::type;
  int n;
  std::vector<T> node;

public:
  // v を基に初期化
  SegmentTree(const std::vector<T> &v) {
    // n は v.size() 以上の最小の2冪
    n = 1;
    while (n < int(v.size()))
      n *= 2;
    node.resize(2 * n - 1, M::id());

    // i の子 -> 2*i+1, 2*i+2 , 親 -> (i-1)/2
    for (int i = 0; i < int(v.size()); i++)
      node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = M::op(node[2 * i + 1], node[2 * i + 2]);
  }
  // Monoid::id 初期化
  SegmentTree(int _n) {
    // n は v.size() 以上の最小の2冪
    n = 1;
    while (n < _n)
      n *= 2;
    node.resize(2 * n - 1, M::id());
  }
  // x 番目を val に更新
  void update(int x, T val) {
    x += n - 1;
    node[x] = val;
    while (x > 0) {
      x = (x - 1) / 2;
      node[x] = M::op(node[2 * x + 1], node[2 * x + 2]);
    }
  }
  // v[x] を M::op(v[x], val) に更新
  void add(int x, T val) {
    x += n - 1;
    node[x] = M::op(node[x], val);
    while (x > 0) {
      x = (x - 1) / 2;
      node[x] = M::op(node[2 * x + 1], node[2 * x + 2]);
    }
  }
  // [a, b) の op
  // k := 今居るノード
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return M::id();
    if (a <= l && r <= b)
      return node[k];

    T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return M::op(vl, vr);
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, q;
  cin >> n >> q;
  vector<ll> a(2 * n), b(2 * n);
  vector<P> v;
  for (int i = 0; i < 2 * n; i++)
    cin >> a[i];
  for (int i = 0; i < 2 * n; i++) {
    cin >> b[i];
    v.emplace_back(P(a[i], b[i]));
  }
  SegmentTree<Query> st(v);
  while (q--) {
    ll p, x, y;
    cin >> p >> x >> y;
    p--;
    a[p] = x;
    b[p] = y;
    st.update(p, P(x, y));
    ll ret = a[0] + a[2 * n - 1] + st.query(1, 2 * n - 1).first;
    cout << ret << endl;
  }
}