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

#include "bits/stdc++.h"
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, a, b) for (int i = (a); i < (b); i++)

using ll = long long;
using Pll = pair<ll, ll>;
const ll inf = 1ll << 60;

template <class T, class E> struct SegTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  typedef function<E(E, E)> H;
  typedef function<E(E, int)> P;
  int n;
  F f;
  G g;
  H h;
  P p;
  T d1;
  E d0;
  vector<T> dat;
  vector<E> lazy;
  SegTree(
      int n_, F f, G g, H h, T d1, E d0, P p = [](E a, int b) { return a; })
      : f(f), g(g), h(h), d1(d1), d0(d0), p(p) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.resize(2 * n - 1, d1);
    lazy.resize(2 * n - 1, d0);
  }
  void build(const vector<E> &a) {
    for (int i = 0; i < a.size(); i++)
      dat[i + n - 1] = Pll(a[i], 1);
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[2 * i + 1], dat[2 * i + 2]);
  }
  void eval(int k, int l, int r) {
    if (lazy[k] == d0)
      return;
    dat[k] = g(dat[k], p(lazy[k], r - l));
    if (k < n - 1) {
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      lazy[2 * k + 2] = h(lazy[2 * k + 2], lazy[k]);
    }
    lazy[k] = d0;
  }
  void update(int a, int b, E x, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    // cerr << "update: a = " << a << ", b = " << b << ", x = " << x << ", k = "
    // << k << ", l = " << l << ", r = " << r << endl;
    eval(k, l, r);
    if (b <= l || r <= a)
      return;
    if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      eval(k, l, r);
    } else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      dat[k] = f(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }
  // return op[a..b)
  // k: node id, [l, r): node interval
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    // cerr << "query: a = " << a << ", b = " << b << ", k = " << k << ", l = "
    // << l << ", r = " << r << endl;
    eval(k, l, r);
    if (r <= a || b <= l)
      return d1;
    if (a <= l && r <= b)
      return dat[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 f(vl, vr);
  }
  void print() {
    int j = 2;
    for (int i = 0; i < 2 * n - 1; i++) {
      cerr << "("
           << "(" << dat[i].first << ", " << dat[i].second << ")"
           << ", " << lazy[i] << ")";
      if (i == j - 2) {
        cerr << endl;
        j *= 2;
      } else {
        cerr << " ";
      }
    }
  }
};

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

  int h, w, q;
  cin >> h >> w >> q;
  vector<ll> a(h);
  rep(i, h) cin >> a[i];
  vector<ll> b(w);
  rep(i, w) cin >> b[i];

  SegTree<Pll, ll> segAm( // Pll = {min, #min}
      h,
      [](Pll a, Pll b) {
        if (a.first < b.first)
          return a;
        else if (a.first > b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(inf, 0), ll(0));

  SegTree<Pll, ll> segAM( // Pll = {max, #max}
      h,
      [](Pll a, Pll b) {
        if (a.first > b.first)
          return a;
        else if (a.first < b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(-inf, 0), ll(0));

  SegTree<Pll, ll> segBm(
      w,
      [](Pll a, Pll b) {
        if (a.first < b.first)
          return a;
        else if (a.first > b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(inf, 0), ll(0));

  SegTree<Pll, ll> segBM(
      w,
      [](Pll a, Pll b) {
        if (a.first > b.first)
          return a;
        else if (a.first < b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(-inf, 0), ll(0));

  segAm.build(a);
  segAM.build(a);
  segBm.build(b);
  segBM.build(b);

  rep(i, q) {
    int t;
    cin >> t;
    if (t == 1 || t == 2) {
      ll l, r, v;
      cin >> l >> r >> v;
      l--;
      if (t == 1) {
        segAm.update(l, r, v);
        segAM.update(l, r, v);
      } else {
        segBm.update(l, r, v);
        segBM.update(l, r, v);
      }
    } else {
      ll la, ra, lb, rb;
      cin >> la >> ra >> lb >> rb;
      la--;
      lb--;
      ll ma, Ma, mb, Mb, cma, cMa, cmb, cMb;
      tie(ma, cma) = segAm.query(la, ra);
      tie(Ma, cMa) = segAM.query(la, ra);
      tie(mb, cmb) = segBm.query(lb, rb);
      tie(Mb, cMb) = segBM.query(lb, rb);

      map<ll, ll> mpA;
      mpA[ma] = cma;
      mpA[Ma] = cMa;
      map<ll, ll> mpB;
      mpB[mb] = cmb;
      mpB[Mb] = cMb;

      map<ll, ll> mp;
      for (auto pa : mpA) {
        for (auto pb : mpB) {
          mp[pa.first * pb.first] += pa.second * pb.second;
        }
      }

      ll ans, cnt;
      if (t == 3)
        tie(ans, cnt) = *(mp.begin());
      else
        tie(ans, cnt) = *(mp.rbegin());

      if (ans == 0) {
        ll cza = mpA[0], czb = mpB[0];

        // 0 = all - non_zero * non_zero
        ll len_a = ra - la;
        ll len_b = rb - lb;
        cnt = len_a * len_b - (len_a - cza) * (len_b - czb);
      }

      cout << ans << " " << cnt << endl;
    }
  }
}


Error: 0

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, a, b) for (int i = (a); i < (b); i++)

using ll = long long;
using Pll = pair<ll, ll>;
const ll inf = 1ll << 60;

template <class T, class E> struct SegTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  typedef function<E(E, E)> H;
  typedef function<E(E, int)> P;
  int n;
  F f;
  G g;
  H h;
  P p;
  T d1;
  E d0;
  vector<T> dat;
  vector<E> lazy;
  SegTree(
      int n_, F f, G g, H h, T d1, E d0, P p = [](E a, int b) { return a; })
      : f(f), g(g), h(h), d1(d1), d0(d0), p(p) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.resize(2 * n - 1, d1);
    lazy.resize(2 * n - 1, d0);
  }
  void build(const vector<E> &a) {
    for (int i = 0; i < a.size(); i++)
      dat[i + n - 1] = Pll(a[i], 1);
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[2 * i + 1], dat[2 * i + 2]);
  }
  void eval(int k, int l, int r) {
    if (lazy[k] == d0)
      return;
    dat[k] = g(dat[k], p(lazy[k], r - l));
    if (k < n - 1) {
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      lazy[2 * k + 2] = h(lazy[2 * k + 2], lazy[k]);
    }
    lazy[k] = d0;
  }
  void update(int a, int b, E x, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    // cerr << "update: a = " << a << ", b = " << b << ", x = " << x << ", k = "
    // << k << ", l = " << l << ", r = " << r << endl;
    eval(k, l, r);
    if (b <= l || r <= a)
      return;
    if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      eval(k, l, r);
    } else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      dat[k] = f(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }
  // return op[a..b)
  // k: node id, [l, r): node interval
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    // cerr << "query: a = " << a << ", b = " << b << ", k = " << k << ", l = "
    // << l << ", r = " << r << endl;
    eval(k, l, r);
    if (r <= a || b <= l)
      return d1;
    if (a <= l && r <= b)
      return dat[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 f(vl, vr);
  }
  void print() {
    int j = 2;
    for (int i = 0; i < 2 * n - 1; i++) {
      cerr << "("
           << "(" << dat[i].first << ", " << dat[i].second << ")"
           << ", " << lazy[i] << ")";
      if (i == j - 2) {
        cerr << endl;
        j *= 2;
      } else {
        cerr << " ";
      }
    }
  }
};

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

  int h, w, q;
  cin >> h >> w >> q;
  vector<ll> a(h);
  rep(i, h) cin >> a[i];
  vector<ll> b(h);
  rep(i, w) cin >> b[i];

  SegTree<Pll, ll> segAm( // Pll = {min, #min}
      h,
      [](Pll a, Pll b) {
        if (a.first < b.first)
          return a;
        else if (a.first > b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(inf, 0), ll(0));

  SegTree<Pll, ll> segAM( // Pll = {max, #max}
      h,
      [](Pll a, Pll b) {
        if (a.first > b.first)
          return a;
        else if (a.first < b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(-inf, 0), ll(0));

  SegTree<Pll, ll> segBm(
      w,
      [](Pll a, Pll b) {
        if (a.first < b.first)
          return a;
        else if (a.first > b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(inf, 0), ll(0));

  SegTree<Pll, ll> segBM(
      w,
      [](Pll a, Pll b) {
        if (a.first > b.first)
          return a;
        else if (a.first < b.first)
          return b;
        else
          return Pll(a.first, a.second + b.second);
      },
      [](Pll a, ll x) { return Pll(a.first + x, a.second); },
      [](ll x, ll y) { return x + y; }, Pll(-inf, 0), ll(0));

  segAm.build(a);
  segAM.build(a);
  segBm.build(b);
  segBM.build(b);

  rep(i, q) {
    int t;
    cin >> t;
    if (t == 1 || t == 2) {
      int l, r, v;
      cin >> l >> r >> v;
      l--;
      if (t == 1) {
        segAm.update(l, r, v);
        segAM.update(l, r, v);

        // cerr << "segAm updated:" << endl;
        // segAm.print();
        // cerr << "segAM updated:" << endl;
        // segAM.print();
      } else {
        segBm.update(l, r, v);
        segBM.update(l, r, v);

        // cerr << "segBm updated:" << endl;
        // segBm.print();
        // cerr << "segBM updated:" << endl;
        // segBM.print();
      }
    } else {
      int la, ra, lb, rb;
      cin >> la >> ra >> lb >> rb;
      la--;
      lb--;
      ll len_a = ra - la;
      ll len_b = rb - lb;
      ll ma, Ma, mb, Mb, cma, cMa, cmb, cMb;
      tie(ma, cma) = segAm.query(la, ra);
      tie(Ma, cMa) = segAM.query(la, ra);
      tie(mb, cmb) = segBm.query(lb, rb);
      tie(Mb, cMb) = segBM.query(lb, rb);

      // cerr << "ma = " << ma << ", Ma = " << Ma << ", mb = " << mb << ", Mb =
      // " << Mb << ", cma = " << cma << ", cMa = " << cMa << ", cmb = " << cmb
      // << ", cMb = " << cMb << endl;

      if (t == 3) {
        // min, #min
        ll cand = inf, cnt = 0;

        // min < 0
        if (ma < 0 && Mb > 0) {
          cand = ma * Mb;
          cnt = cma * cMb;
        }
        if (Ma > 0 && mb < 0) {
          if (Ma * mb < cand) {
            cand = Ma * mb;
            cnt = cMa * cmb;
          } else if (Ma * mb == cand) {
            cnt += cMa * cmb;
          }
        }

        if (cand == inf) {
          if (ma == 0 || Ma == 0 || mb == 0 || Mb == 0) {
            // min = 0
            cand = 0;

            ll cza = 0; // #0
            if (ma == 0)
              cza = cma;
            else if (Ma == 0)
              cza = cMa;

            ll czb = 0; // #0
            if (mb == 0)
              czb = cmb;
            else if (Mb == 0)
              czb = cMb;

            // 0 = all - non_zero * non_zero
            cnt = len_a * len_b - (len_a - cza) * (len_b - czb);
          } else {
            // min > 0
            if (ma > 0 && mb > 0) {
              // (+) * (+)
              cand = ma * mb;
              cnt = cma * cmb;
            }
            if (Ma < 0 && Mb < 0) {
              // (-) * (-)
              if (Ma * Mb < cand) {
                cand = Ma * Mb;
                cnt = cMa * cMb;
              } else if (Ma * Mb == cand) {
                cnt += cMa * cMb;
              }
            }
          }
        }

        // assert(cand != -inf);
        // assert(cnt > 0);
        // cout << "i = " << i + 1 << endl;
        cout << cand << " " << cnt << endl;
      } else {
        // max, #max
        ll cand = -inf, cnt = 0;

        // max > 0
        if (Ma > 0 && Mb > 0) {
          cand = Ma * Mb;
          cnt = cMa * cMb;
        }
        if (ma < 0 && mb < 0) {
          if (ma * mb > cand) {
            cand = ma * mb;
            cnt = cma * cmb;
          } else if (ma * mb == cand) {
            cnt += cma * cmb;
          }
        }

        if (cand == inf) {
          if (ma == 0 || Ma == 0 || mb == 0 || Mb == 0) {
            // max = 0
            cand = 0;

            ll cza = 0; // #0
            if (ma == 0)
              cza = cma;
            else if (Ma == 0)
              cza = cMa;

            ll czb = 0; // #0
            if (mb == 0)
              czb = cmb;
            else if (Mb == 0)
              czb = cMb;

            // 0 = all - non_zero * non_zero
            cnt = len_a * len_b - (len_a - cza) * (len_b - czb);
          } else {
            // max < 0
            if (Ma < 0 && 0 < mb) {
              // (-) * (+)
              cand = Ma * mb;
              cnt = cMa * cmb;
            }
            if (mb < 0 && 0 < Ma) {
              // (-) * (+)
              if (mb * Ma > cand) {
                cand = mb * Ma;
                cnt = cmb * cMa;
              } else if (mb * Ma == cand) {
                cnt += cmb * cMa;
              }
            }
          }
        }

        // assert(cand != inf);
        // assert(cnt > 0);
        // cout << "i = " << i + 1 << endl;
        cout << cand << " " << cnt << endl;
      }
    }
  }
}