Language: C++

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll INF= 1LL<<60;
template <typename Base>
class LazySegmentTree
{
public:
    using BaseAlgebra = Base;
    using AccMonoid = typename BaseAlgebra::AccMonoid;
    using OpMonoid = typename BaseAlgebra::OpMonoid;
    using T = typename BaseAlgebra::T;
    using F = typename BaseAlgebra::OpMonoid::T;
    LazySegmentTree(const int n)
        : data_num(n), size(1 << (1 + __lg(2 * data_num - 1))), half(size >> 1), value(size, AccMonoid::identity()), action(size, OpMonoid::identity()) { assert(n > 0); }
    LazySegmentTree(const std::vector<T>& val)
        : data_num(val.size()), size(1 << (1 + __lg(2 * data_num - 1))), half(size >> 1), value(size), action(size, OpMonoid::identity())
    {
        for (int data = 0; data < half; data++) {
            if (data < data_num) {
                value[data + half] = val[data];
            } else {
                value[data + half] = AccMonoid::identity();
            }
        }
        for (int node = half - 1; node >= 1; node--) {
            value[node] = acc(value[2 * node], value[2 * node + 1]);
        }
    }
    T get(const int a) const
    {
        assert(0 <= a and a < data_num);
        return accumulate(a, a + 1);
    }
    void set(const int a, const T& val)
    {
        assert(0 <= a and a < data_num);
        const int node = a + half;
        value[node] = val;
        for (int i = node / 2; i > 0; i /= 2) {
            value[i] = acc(value[2 * i], value[2 * i + 1]);
        }
    }
    T accumulate(const int a, const int b) const  // Accumulate (a,b]
    {
        assert(0 <= a and a < b and b <= data_num);
        return accumulateRec(1, 0, half, a, b);
    }
    void modify(const int a, const int b, const F& f)  // Apply f on (a,b]
    {
        assert(0 <= a and a < b and b <= data_num);
        if (f == OpMonoid::identity()) {
            return;
        }
        modifyRec(1, 0, half, a, b, f);
    }
    const int data_num;  // Num of valid data on leaves.
private:
    void modifyRec(const int range_index, const int range_left, const int range_right, const int op_left, const int op_right, const F& f)
    {
        if (op_left <= range_left and range_right <= op_right) {
            value[range_index] = act(f, value[range_index]);
            action[range_index] = compose(f, action[range_index]);
        } else if (range_right <= op_left or op_right <= range_left) {
            // Do nothing
        } else {
            modifyRec(2 * range_index, range_left, (range_left + range_right) / 2, 0, half, action[range_index]);
            modifyRec(2 * range_index, range_left, (range_left + range_right) / 2, op_left, op_right, f);
            modifyRec(2 * range_index + 1, (range_left + range_right) / 2, range_right, 0, half, action[range_index]);
            modifyRec(2 * range_index + 1, (range_left + range_right) / 2, range_right, op_left, op_right, f);
            value[range_index] = acc(value[2 * range_index], value[2 * range_index + 1]);
            action[range_index] = OpMonoid::identity();
        }
    }
    T accumulateRec(const int range_index, const int range_left, const int range_right, const int op_left, const int op_right) const
    {
        if (op_left <= range_left and range_right <= op_right) {
            return value[range_index];
        } else if (range_right <= op_left or op_right <= range_left) {
            return AccMonoid::identity();
        } else {
            return act(action[range_index], acc(accumulateRec(2 * range_index, range_left, (range_left + range_right) / 2, op_left, op_right), accumulateRec(2 * range_index + 1, (range_left + range_right) / 2, range_right, op_left, op_right)));
        }
    }
    const int size;
    const int half;
    vector<T> value;   // Tree for value(length: size)
    vector<F> action;  // Tree for action(length: half)
    const AccMonoid acc{};
    const OpMonoid compose{};
    const BaseAlgebra act{};
};

struct MinNum_Plus
{
    using T = pair<ll,int>;

    struct AccMonoid
    {
        T operator()(const T& a, const T& b) const { 
            return a.first==b.first?T{a.first,a.second+b.second}:a.first < b.first?a:b; 
        }
        static constexpr T identity() { return {INF,0}; }
    };

    struct OpMonoid
    {
        using T = ll;
        T operator()(const T& f1, const T& f2) const { return f1 + f2; }
        static constexpr T identity() { return 0; }
    };

    T operator()(const OpMonoid::T& f, const T& x) const { return {f+x.first,x.second}; }
};

struct MaxNum_Plus
{
    using T = pair<ll,int>;

    struct AccMonoid
    {
        T operator()(const T& a, const T& b) const { 
            return a.first==b.first?T{a.first,a.second+b.second}:a.first > b.first?a:b; 
        }
        static constexpr T identity() { return {-INF,0}; }
    };

    struct OpMonoid
    {
        using T = ll;
        T operator()(const T& f1, const T& f2) const { return f1 + f2; }
        static constexpr T identity() { return 0; }
    };

    T operator()(const OpMonoid::T& f, const T& x) const { return {f+x.first,x.second}; }
};
using MinSeg = LazySegmentTree<MinNum_Plus>;
using MaxSeg = LazySegmentTree<MaxNum_Plus>;

using P = pair<ll,ll>;
inline P get(const P& pmin, const P& pmax, const P& qmin,const P& qmax, const bool minimum, const int h, const int w)
{
    vector<P> v = {
        P{pmin.first*qmin.first,pmin.second*qmin.second},
        P{pmin.first*qmax.first,pmin.second*qmax.second},
        P{pmax.first*qmin.first,pmax.second*qmin.second},
        P{pmax.first*qmax.first,pmax.second*qmax.second},
        };
    sort(v.begin(),v.end());
    const auto ans = minimum?v.front():v.back();
    if(ans.first != 0){
        return ans;
    } else {
        const ll z1 = pmin.first==0?pmin.second:pmax.first==0?pmax.second:0;
        const ll z2 = qmin.first==0?qmin.second:qmax.first==0?qmax.second:0;
        return {0,z1*w+z2*h-z1*z2};
    }
}

int main()
{
    int H, W,Q;
    cin >> H >> W >> Q;
    vector<pair<ll,ll>> A(H);
    for(int i = 0; i < H; i++){
        cin >> A[i].first;
        A[i].second = 1;
    }
    vector<pair<ll,int>> B(W);
    for(int i = 0; i < W; i++){
        cin >> B[i].first;
        B[i].second=1;
    }
    MinSeg amin(A);
    MaxSeg amax(A);
    MinSeg bmin(B);
    MaxSeg bmax(B);
    for(int q = 0; q < Q; q++){
        int t;
        cin >> t;
        int a, b;
        cin >> a >> b;
        a--;
        if(t == 1){
            ll v;
            cin >> v;
            amin.modify(a,b,v);
            amax.modify(a,b,v);
        } else if(t == 2){
            ll v;
            cin >> v;
            bmin.modify(a,b,v);
            bmax.modify(a,b,v);
        } else if(t == 3){
            int c, d;
            cin >> c >> d;
            c--;
            const auto AMIN = amin.accumulate(a,b);
            const auto AMAX = amax.accumulate(a,b);
            const auto BMIN = bmin.accumulate(c,d);
            const auto BMAX = bmax.accumulate(c,d);
            const auto ans = get(AMIN,AMAX,BMIN,BMAX,true,b-a,d-c);
            cout << ans.first << " " << ans.second << endl;
        } else {
            int c, d;
            cin >> c >> d;
            c--;
            const auto AMIN = amin.accumulate(a,b);
            const auto AMAX = amax.accumulate(a,b);
            const auto BMIN = bmin.accumulate(c,d);
            const auto BMAX = bmax.accumulate(c,d);
            const auto ans = get(AMIN,AMAX,BMIN,BMAX,false,b-a,d-c);
            cout << ans.first << " " << ans.second << endl;
        }
    }
    return 0;
}


Compiler output:
a.cc: In function 'int main()':
a.cc:174:18: error: no matching function for call to 'LazySegmentTree<MinNum_Plus>::LazySegmentTree(std::vector<std::pair<long long int, long long int> >&)'
  174 |     MinSeg amin(A);
      |                  ^
a.cc:16:5: note: candidate: 'LazySegmentTree<Base>::LazySegmentTree(const std::vector<typename Base::T>&) [with Base = MinNum_Plus; typename Base::T = std::pair<long long int, int>]'
   16 |     LazySegmentTree(const std::vector<T>& val)
      |     ^~~~~~~~~~~~~~~
a.cc:16:43: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'const std::vector<std::pair<long long int, int> >&'
   16 |     LazySegmentTree(const std::vector<T>& val)
      |                     ~~~~~~~~~~~~~~~~~~~~~~^~~
a.cc:14:5: note: candidate: 'LazySegmentTree<Base>::LazySegmentTree(int) [with Base = MinNum_Plus]'
   14 |     LazySegmentTree(const int n)
      |     ^~~~~~~~~~~~~~~
a.cc:14:31: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'int'
   14 |     LazySegmentTree(const int n)
      |                     ~~~~~~~~~~^
a.cc:6:7: note: candidate: 'LazySegmentTree<MinNum_Plus>::LazySegmentTree(const LazySegmentTree<MinNum_Plus>&)'
    6 | class LazySegmentTree
      |       ^~~~~~~~~~~~~~~
a.cc:6:7: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'const LazySegmentTree<MinNum_Plus>&'
a.cc:6:7: note: candidate: 'LazySegmentTree<MinNum_Plus>::LazySegmentTree(LazySegmentTree<MinNum_Plus>&&)'
a.cc:6:7: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'LazySegmentTree<MinNum_Plus>&&'
a.cc:175:18: error: no matching function for call to 'LazySegmentTree<MaxNum_Plus>::LazySegmentTree(std::vector<std::pair<long long int, long long int> >&)'
  175 |     MaxSeg amax(A);
      |                  ^
a.cc:16:5: note: candidate: 'LazySegmentTree<Base>::LazySegmentTree(const std::vector<typename Base::T>&) [with Base = MaxNum_Plus; typename Base::T = std::pair<long long int, int>]'
   16 |     LazySegmentTree(const std::vector<T>& val)
      |     ^~~~~~~~~~~~~~~
a.cc:16:43: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'const std::vector<std::pair<long long int, int> >&'
   16 |     LazySegmentTree(const std::vector<T>& val)
      |                     ~~~~~~~~~~~~~~~~~~~~~~^~~
a.cc:14:5: note: candidate: 'LazySegmentTree<Base>::LazySegmentTree(int) [with Base = MaxNum_Plus]'
   14 |     LazySegmentTree(const int n)
      |     ^~~~~~~~~~~~~~~
a.cc:14:31: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'int'
   14 |     LazySegmentTree(const int n)
      |                     ~~~~~~~~~~^
a.cc:6:7: note: candidate: 'LazySegmentTree<MaxNum_Plus>::LazySegmentTree(const LazySegmentTree<MaxNum_Plus>&)'
    6 | class LazySegmentTree
      |       ^~~~~~~~~~~~~~~
a.cc:6:7: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'const LazySegmentTree<MaxNum_Plus>&'
a.cc:6:7: note: candidate: 'LazySegmentTree<MaxNum_Plus>::LazySegmentTree(LazySegmentTree<MaxNum_Plus>&&)'
a.cc:6:7: note:   no known conversion for argument 1 from 'std::vector<std::pair<long long int, long long int> >' to 'LazySegmentTree<MaxNum_Plus>&&'