Problem:
Problem J: Matrix

Problem

長さ$H$の数列$A$と長さ$W$の数列$B$が与えられる。

$H$行$W$列からなる行列$C$を以下のように定義する。

$ C_{i,j} = A_i \times B_j (1 \leq i \leq H, 1 \leq j \leq W) $

以下の四種類のクエリを合計$Q$回処理せよ。

クエリ1

$1$ $a$ $b$ $v$

$ A_i ( a \leq i \leq b) $に$v$を加える

クエリ2

$2$ $c$ $d$ $v$

$ B_j ( c \leq j \leq d) $に$v$を加える

クエリ3

$3$ $a$ $b$ $c$ $d$

$ C_{i,j} ( a \leq i \leq b, c \leq j \leq d) $の最小値とその個数を出力する

クエリ4

$4$ $a$ $b$ $c$ $d$

$ C_{i,j} ( a \leq i \leq b, c \leq j \leq d) $の最大値とその個数を出力する

詳しくはサンプル入出力を参考にせよ。

Input

入力は以下の形式で与えられる。

$H$ $W$ $Q$
$A_1$ $A_2$ ... $A_H$
$B_1$ $B_2$ ... $B_W$
$query_1$
$query_2$
...
$query_Q$

各クエリは以下の四種類のいずれかの形式で与えられる。

$1$ $a$ $b$ $v$
$2$ $c$ $d$ $v$
$3$ $a$ $b$ $c$ $d$
$4$ $a$ $b$ $c$ $d$

入力はすべて整数で与えられる。

1行目に$H$, $W$, $Q$が空白区切りで与えられる。

2行目に数列$A$の要素$A_i$($1 \leq i \leq H$)が空白区切りで与えられる。

3行目に数列$B$の要素$B_j$($1 \leq j \leq W$)が空白区切りで与えられる。

4行目以降の$Q$行にクエリが改行区切りで与えられる。

各クエリ内の数値は全て空白区切りである。

Constraints

入力は以下の条件を満たす。

$1 \leq H, W, Q\leq 10^5 $

$-1000 \leq A_i \leq 1000 $

$-1000 \leq B_j \leq 1000 $

各クエリについて、入力は以下の条件を満たす。

$1 \leq a \leq b \leq H$

$1 \leq c \leq d \leq W$

$-1000 \leq v \leq 1000$

Output

各クエリ3及びクエリ4について、値と個数を空白区切りで一行に出力せよ。

Sample Input 1

4 4 7
1 2 3 4
1 2 3 4
3 2 3 2 3
4 2 3 2 3
3 1 1 1 1
4 1 1 1 1
1 1 1 1
3 1 4 1 2
4 2 3 2 4

Sample Output 1

4 1
9 1
1 1
1 1
2 2
12 1

クエリ1, 2で指定されている範囲は以下の画像の緑色に塗られた領域である。

クエリ3, 4で指定されている範囲は以下の画像の橙色に塗られた領域である。

クエリ5によって$A_1$に1が加えられる。

クエリ6で指定されている範囲は以下の画像の水色に塗られた領域である。

クエリ7で指定されている範囲は以下の画像の紫色に塗られた領域である。

Sample Input 2

4 4 6
1 1 1 1
1 1 1 1
3 1 4 1 4
4 1 4 1 4
1 2 3 1
2 2 3 1
3 1 4 1 4
4 1 4 1 4

Sample Output 2

1 16
1 16
1 4
4 4

初期状態の$C$は以下のようになる。

クエリ3, 4以後の$C$は以下のようになる。

Sample Input 3

4 4 7
0 1 0 1
1 0 1 0
3 2 4 1 3
4 1 4 1 4
1 1 4 -1
3 1 3 1 3
1 3 3 2
2 3 3 -2
3 2 4 2 4

Sample Output 3

0 5
1 4
-1 4
-1 1

Sample Input 4

36 4 20
-523 -460 -536 -885 652 782 513 -558 -521 -808 124 -708 -943 52 -856 -755 -958 913 380 -767 373 -731 -492 213 538 392 -39 509 -840 135 78 -285 -241 522 -572 -915
-691 -16 812 -385
4 7 17 4 4
3 24 33 1 1
4 3 35 2 4
3 28 32 4 4
2 3 3 438
3 7 15 1 1
4 2 17 4 4
3 24 28 2 4
4 15 16 4 4
4 18 29 1 1
3 24 27 2 4
2 2 3 -828
3 18 23 3 3
1 27 31 -701
2 2 3 298
1 21 32 237
2 3 3 -71
1 14 29 772
4 13 19 3 3
3 19 34 1 2

Sample Output 4

368830 1
-371758 1
741356 1
-195965 1
-354483 1
368830 1
-207130 1
329560 1
580440 1
-207130 1
-323674 1
1093565 1
-1068977 1

Solution in C++14 (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

// const int B = 6;
// const int SZ = 6;

const int B = 400;
const int SZ = 250;

const int INF = 123456789;
const ll LINF = LLONG_MAX/3;

int X[2];

int x[2][B][SZ];
int ADD[2][B];

int MIN[2][B], MAX[2][B];
map<int,int> ct[2][B];

void update(int t, int bid){
    MIN[t][bid] = INF;
    MAX[t][bid] = -INF;
    ct[t][bid].clear();

    rep(i,SZ){
        int idx = bid*SZ+i;
        if(idx>=X[t]) break;

        MIN[t][bid] = min(MIN[t][bid], x[t][bid][i]);
        MAX[t][bid] = max(MAX[t][bid], x[t][bid][i]);
        ++ct[t][bid][x[t][bid][i]];
    }
}

void push(int t, int bid){
    if(ADD[t][bid]==0) return;

    rep(i,SZ){
        int idx = bid*SZ+i;
        if(idx>=X[t]) break;
        x[t][bid][i] += ADD[t][bid];
    }
    ADD[t][bid]=0;

    update(t,bid);
}

void add(int t, int l, int r, int v){
    int lid = l/SZ, rid = r/SZ;
    push(t,lid);
    push(t,rid);
    if(lid==rid){
        for(int i=l; i<=r; ++i) x[t][lid][i%SZ] += v;
        update(t,lid);
    }
    else{
        for(int bid = lid+1; bid < rid; ++bid){
            ADD[t][bid] += v;
            MAX[t][bid] += v;
            MIN[t][bid] += v;
        }

        for(int i=l; i<SZ*(lid+1); ++i) x[t][lid][i%SZ] += v;
        for(int i=SZ*rid; i<=r; ++i) x[t][rid][i%SZ] += v;
        update(t,lid);
        update(t,rid);
    }
}

ll max_query(int t, int l, int r){
    int lid = l/SZ, rid = r/SZ;
    int ret = -INF;

    push(t,lid);
    push(t,rid);
    update(t,lid);
    update(t,rid);

    if(lid==rid){
        for(int i=l; i<=r; ++i) ret = max(ret, x[t][lid][i%SZ]+ADD[t][lid]);
    }
    else{
        for(int bid = lid+1; bid < rid; ++bid) ret = max(ret, MAX[t][bid]+ADD[t][bid]);

        for(int i=l; i<SZ*(lid+1); ++i) ret = max(ret, x[t][lid][i%SZ]+ADD[t][lid]);
        for(int i=SZ*rid; i<=r; ++i) ret = max(ret, x[t][rid][i%SZ]+ADD[t][rid]);
    }
    return (ll)ret;
}

ll min_query(int t, int l, int r){
    int lid = l/SZ, rid = r/SZ;
    int ret = INF;

    push(t,lid);
    push(t,rid);
    update(t,lid);
    update(t,rid);

    if(lid==rid){
        for(int i=l; i<=r; ++i) ret = min(ret, x[t][lid][i%SZ]+ADD[t][lid]);
    }
    else{
        for(int bid = lid+1; bid < rid; ++bid) ret = min(ret, MAX[t][bid]+ADD[t][bid]);

        for(int i=l; i<SZ*(lid+1); ++i) ret = min(ret, x[t][lid][i%SZ]+ADD[t][lid]);
        for(int i=SZ*rid; i<=r; ++i) ret = min(ret, x[t][rid][i%SZ]+ADD[t][rid]);
    }
    return (ll)ret;
}

ll cnt(int t, int l, int r, int v){
    int ret = 0;
    int lid = l/SZ, rid = r/SZ;

    if(lid==rid){
        for(int i=l; i<=r; ++i){
            if(x[t][lid][i%SZ]+ADD[t][lid] == v) ++ret;
        }
    }
    else{
        for(int bid = lid+1; bid < rid; ++bid){
            int focus = v-ADD[t][bid];
            if(ct[t][bid].count(focus)) ret += ct[t][bid][focus];
        }

        for(int i=l; i<SZ*(lid+1); ++i){
            if(x[t][lid][i%SZ]+ADD[t][lid] == v) ++ret;
        }
        for(int i=SZ*rid; i<=r; ++i){
            if(x[t][rid][i%SZ]+ADD[t][rid] == v) ++ret;
        }
    }

    return (ll)ret;
}

int main(){
    int q;
    scanf(" %d %d %d", &X[0], &X[1], &q);

    rep(i,2){
        rep(j,X[i]){
            int v;
            scanf(" %d", &v);
            x[i][j/SZ][j%SZ] = v;
        }

        rep(j,B) update(i,j);
    }

    while(q--){
        int t;
        scanf(" %d", &t);

        if(t<=2){
            int l,r,v;
            scanf(" %d %d %d", &l, &r, &v);
            --l; --r;
            add(t-1,l,r,v);
        }
        else{
            int l[2],r[2];
            rep(i,2){
                scanf(" %d %d", &l[i], &r[i]);
                --l[i]; --r[i];
            }

            ll C;
            ll ans = 0;

            if(t==3){
                // MIN QUERY
                C = LINF;
                rep(i,2)rep(j,2){
                    ll va,vb;
                    if(i) va = max_query(0,l[0],r[0]);
                    else va = min_query(0,l[0],r[0]);

                    if(j) vb = max_query(1,l[1],r[1]);
                    else vb = min_query(1,l[1],r[1]);

                    C = min(C, va*vb);
                }

                if(C==0){
                    ll a0 = cnt(0,l[0],r[0],0);
                    ll b0 = cnt(1,l[1],r[1],0);

                    ans += a0*(r[1]-l[1]+1);
                    ans += b0*(r[0]-l[0]+1);
                    ans -= a0*b0;
                }
                else{
                    set<pair<ll,ll>> S;
                    rep(i,2)rep(j,2){
                        ll va,vb;
                        if(i) va = max_query(0,l[0],r[0]);
                        else va = min_query(0,l[0],r[0]);

                        if(j) vb = max_query(1,l[1],r[1]);
                        else vb = min_query(1,l[1],r[1]);

                        if(va*vb == C) S.insert({va,vb});
                    }

                    for(const auto &p:S){
                        int va = p.fi, vb = p.se;
                        ans += cnt(0,l[0],r[0],va) * cnt(1,l[1],r[1],vb);
                    }
                }
            }
            else{
                // MAX QUERY
                C = -LINF;
                rep(i,2)rep(j,2){
                    ll va,vb;
                    if(i) va = max_query(0,l[0],r[0]);
                    else va = min_query(0,l[0],r[0]);

                    if(j) vb = max_query(1,l[1],r[1]);
                    else vb = min_query(1,l[1],r[1]);

                    C = max(C, va*vb);
                }

                if(C==0){
                    ll a0 = cnt(0,l[0],r[0],0);
                    ll b0 = cnt(1,l[1],r[1],0);

                    ans += a0*(r[1]-l[1]+1);
                    ans += b0*(r[0]-l[0]+1);
                    ans -= a0*b0;
                }
                else{
                    set<pair<ll,ll>> S;
                    rep(i,2)rep(j,2){
                        ll va,vb;
                        if(i) va = max_query(0,l[0],r[0]);
                        else va = min_query(0,l[0],r[0]);

                        if(j) vb = max_query(1,l[1],r[1]);
                        else vb = min_query(1,l[1],r[1]);

                        if(va*vb == C) S.insert({va,vb});
                    }

                    for(const auto &p:S){
                        int va = p.fi, vb = p.se;
                        ans += cnt(0,l[0],r[0],va) * cnt(1,l[1],r[1],vb);
                    }
                }
            }

            printf("%lld %lld\n", C, ans);
        }
    }

    return 0;
}