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

#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid, int)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

  int sz;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &M1,
                  const OperatorMonoid OM0)
      : f(f), g(g), h(h), M1(M1), OM0(OM0) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  void propagate(int k, int len) {
    if (lazy[k] != OM0) {
      if (k < sz) {
        lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
        lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      }
      data[k] = g(data[k], lazy[k], len);
      lazy[k] = OM0;
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return data[k];
    } else if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      propagate(k, r - l);
      return data[k];
    } else {
      return data[k] = f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
                         update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x) {
    return update(a, b, x, 1, 0, sz);
  }

  Monoid query(int a, int b, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return M1;
    } else if (a <= l && r <= b) {
      return data[k];
    } else {
      return f(query(a, b, 2 * k + 0, l, (l + r) >> 1),
               query(a, b, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid query(int a, int b) { return query(a, b, 1, 0, sz); }

  Monoid operator[](const int &k) { return query(k, k + 1); }
};

const int64 INF = 1LL << 30;
const int64 LINF = 1LL << 62;

struct Tap {
  int64 large, large_count;
  int64 small, small_count;
} e((Tap){-INF, 0, INF, 0});

int main() {
  int H, W, Q, A[100000], B[100000];
  scanf("%d %d %d", &H, &W, &Q);

  auto f = [](const Tap &x, const Tap &y) {
    Tap z;
    z.small_count = z.large_count = 0;
    z.large = max(x.large, y.large);
    if (z.large == x.large)
      z.large_count += x.large_count;
    if (z.large == y.large)
      z.large_count += y.large_count;
    z.small = min(x.small, y.small);
    if (z.small == x.small)
      z.small_count += x.small_count;
    if (z.small == y.small)
      z.small_count += y.small_count;
    return z;
  };
  auto g = [](Tap x, int64 v, int len) {
    x.large += v;
    x.small += v;
    return x;
  };
  auto h = [](int64 x, int64 y) { return x + y; };

  LazySegmentTree<Tap, int64> latte(H, f, g, h, e, 0), malta(W, f, g, h, e, 0);
  for (int i = 0; i < H; i++) {
    int x;
    scanf("%d", &x);
    latte.set(i, (Tap){x, 1, x, 1});
  }
  for (int i = 0; i < W; i++) {
    int x;
    scanf("%d", &x);
    malta.set(i, (Tap){x, 1, x, 1});
  }
  latte.build();
  malta.build();
  while (Q--) {
    int t, a, b, c, d;
    scanf("%d %d %d %d", &t, &a, &b, &c);
    if (t <= 2) {
      --a;
      (t == 1 ? latte : malta).update(a, b, c);
    } else if (t == 4) {
      scanf("%d", &d);
      auto p = latte.query(--a, b), q = malta.query(--c, d);
      int64 ret = -LINF, sum = 0;
      if (p.large > 0 && q.large > 0) {
        ret = p.large * q.large;
        sum = p.large_count * q.large_count;
      }
      if (p.small < 0 && q.small < 0 && p.small * q.small >= ret) {
        if (p.small * q.small > ret)
          sum = 0;
        ret = p.small * q.small;
        sum += p.small_count * q.small_count;
      }
      if (ret != -LINF) {
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.small == 0) {
        ret = sum = 0;
        sum += p.small_count * (d - c);
        if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.small_count;
        } else if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.small_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.large == 0) {
        ret = sum = 0;
        sum += p.large_count * (d - c);
        if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.large_count;
        } else if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.large_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (q.small == 0) {
        ret = sum = 0;
        sum += q.small_count * (b - a);
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (q.large == 0) {
        ret = sum = 0;
        sum += q.large_count * (b - a);
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      for (int lattemalta = 0; lattemalta < 2; lattemalta++) {
        swap(p, q);
        if (p.large < 0 && q.small > 0 && p.large * q.small >= ret) {
          if (p.large * q.small > ret)
            sum = 0;
          ret = p.large * q.small;
          sum += p.large_count * q.small_count;
        }
      }

      printf("%lld %lld\\n", ret, sum);

    } else {
      scanf("%d", &d);
      auto p = latte.query(--a, b), q = malta.query(--c, d);
      int64 ret = LINF, sum = 0;

      if (p.small < 0 && q.large > 0 && p.small * q.large <= ret) {
        if (p.small * q.large < ret)
          sum = 0;
        ret = p.small * q.large;
        sum += p.small_count * q.large_count;
      }

      if (p.large > 0 && q.small < 0 && p.large * q.small <= ret) {
        if (p.large * q.small < ret)
          sum = 0;
        ret = p.large * q.small;
        sum += p.large_count * q.small_count;
      }

      if (ret != LINF) {
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.large == 0) {
        ret = sum = 0;
        sum += p.large_count * (d - c);
        if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.large_count;
        } else if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.large_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.small == 0) {
        ret = sum = 0;
        sum += p.small_count * (d - c);
        if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.small_count;
        } else if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.small_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (q.small == 0) {
        ret = sum = 0;
        sum += q.small_count * (b - a);
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (q.large == 0) {
        ret = sum = 0;
        sum += q.large_count * (b - a);
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.small > 0 && q.small > 0) {
        ret = p.small * q.small;
        sum += p.small_count * q.small_count;
      }

      if (p.large < 0 && q.large < 0 && p.large * q.large <= ret) {
        if (p.large * q.large < ret)
          sum = 0;
        ret = p.large * q.large;
        sum += p.large_count * q.large_count;
      }
      printf("%lld %lld\\n", ret, sum);
    }
  }
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid, int)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

  int sz;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &M1,
                  const OperatorMonoid OM0)
      : f(f), g(g), h(h), M1(M1), OM0(OM0) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  void propagate(int k, int len) {
    if (lazy[k] != OM0) {
      if (k < sz) {
        lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
        lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      }
      data[k] = g(data[k], lazy[k], len);
      lazy[k] = OM0;
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return data[k];
    } else if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      propagate(k, r - l);
      return data[k];
    } else {
      return data[k] = f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
                         update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x) {
    return update(a, b, x, 1, 0, sz);
  }

  Monoid query(int a, int b, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return M1;
    } else if (a <= l && r <= b) {
      return data[k];
    } else {
      return f(query(a, b, 2 * k + 0, l, (l + r) >> 1),
               query(a, b, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid query(int a, int b) { return query(a, b, 1, 0, sz); }

  Monoid operator[](const int &k) { return query(k, k + 1); }
};

const int64 INF = 1LL << 30;
const int64 LINF = 1LL << 62;

struct Tap {
  int64 large, large_count;
  int64 small, small_count;
} e((Tap){-INF, 0, INF, 0});

int main() {
  int H, W, Q, A[100000], B[100000];
  scanf("%d %d %d", &H, &W, &Q);

  auto f = [](const Tap &x, const Tap &y) {
    Tap z;
    z.small_count = z.large_count = 0;
    z.large = max(x.large, y.large);
    if (z.large == x.large)
      z.large_count += x.large_count;
    if (z.large == y.large)
      z.large_count += y.large_count;
    z.small = min(x.small, y.small);
    if (z.small == x.small)
      z.small_count += x.small_count;
    if (z.small == y.small)
      z.small_count += y.small_count;
    return z;
  };
  auto g = [](Tap x, int64 v, int len) {
    x.large += v;
    x.small += v;
    return x;
  };
  auto h = [](int64 x, int64 y) { return x + y; };

  LazySegmentTree<Tap, int64> latte(H, f, g, h, e, 0), malta(W, f, g, h, e, 0);
  for (int i = 0; i < H; i++) {
    int x;
    scanf("%d", &x);
    latte.set(i, (Tap){x, 1, x, 1});
  }
  for (int i = 0; i < W; i++) {
    int x;
    scanf("%d", &x);
    malta.set(i, (Tap){x, 1, x, 1});
  }
  latte.build();
  malta.build();
  while (Q--) {
    fflush(stdout);

    int t, a, b, c, d;
    scanf("%d %d %d %d", &t, &a, &b, &c);
    if (t <= 2) {
      --a;
      (t == 1 ? latte : malta).update(a, b, c);
    } else if (t == 4) {
      scanf("%d", &d);
      auto p = latte.query(--a, b), q = malta.query(--c, d);
      int64 ret = -LINF, sum = 0;
      if (p.large > 0 && q.large > 0) {
        ret = p.large * q.large;
        sum = p.large_count * q.large_count;
      }
      if (p.small < 0 && q.small < 0 && p.small * q.small >= ret) {
        if (p.small * q.small > ret)
          sum = 0;
        ret = p.small * q.small;
        sum += p.small_count * q.small_count;
      }
      if (ret != -LINF) {
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.small == 0) {
        ret = sum = 0;
        sum += p.small_count * (d - c);
        if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.small_count;
        } else if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.small_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.large == 0) {
        ret = sum = 0;
        sum += p.large_count * (d - c);
        if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.large_count;
        } else if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.large_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }
      assert(q.small != 0);
      assert(q.large != 0);

      for (int lattemalta = 0; lattemalta < 2; lattemalta++) {
        swap(p, q);
        if (p.large < 0 && q.small > 0 && p.large * q.small >= ret) {
          if (p.large * q.small > ret)
            sum = 0;
          ret = p.large * q.small;
          sum += p.large_count * q.small_count;
        }
      }

      printf("%lld %lld\\n", ret, sum);

    } else {
      scanf("%d", &d);
      auto p = latte.query(--a, b), q = malta.query(--c, d);
      int64 ret = LINF, sum = 0;

      if (p.small < 0 && q.large > 0 && p.small * q.large <= ret) {
        if (p.small * q.large < ret)
          sum = 0;
        ret = p.small * q.large;
        sum += p.small_count * q.large_count;
      }

      if (p.large > 0 && q.small < 0 && p.large * q.small <= ret) {
        if (p.large * q.small < ret)
          sum = 0;
        ret = p.large * q.small;
        sum += p.large_count * q.small_count;
      }

      if (ret != LINF) {
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.large == 0) {
        ret = sum = 0;
        sum += p.large_count * (d - c);
        if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.large_count;
        } else if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.large_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      if (p.small == 0) {
        ret = sum = 0;
        sum += p.small_count * (d - c);
        if (q.large == 0) {
          sum += q.large_count * (b - a);
          sum -= q.large_count * p.small_count;
        } else if (q.small == 0) {
          sum += q.small_count * (b - a);
          sum -= q.small_count * p.small_count;
        }
        printf("%lld %lld\\n", ret, sum);
        continue;
      }

      assert(q.small != 0);
      assert(q.large != 0);

      if (p.small > 0 && q.small > 0) {
        ret = p.small * q.small;
        sum += p.small_count * q.small_count;
      }

      if (p.large < 0 && q.large < 0 && p.large * q.large <= ret) {
        if (p.large * q.large < ret)
          sum = 0;
        ret = p.large * q.large;
        sum += p.large_count * q.large_count;
      }
      printf("%lld %lld\\n", ret, sum);
    }
  }
}