为啥还 T 了,25pts
#include <bits/stdc++.h>
#define int long long
#define f(i ,m ,n ,x) for (int i = (m) ;i <= (n) ;i += (x))
#define ls (cur << 1)
#define rs (cur << 1 | 1)
using namespace std ;
const int inf = 1e18 + 1 ;
template < typename T > inline void read ( T &x ) {
x = 0 ;
bool flag (0) ;
register char ch = getchar () ;
while (! isdigit (ch)) {
flag = ch == '-' ;
ch = getchar () ;
}
while (isdigit (ch)) {
x = (x << 1) + (x << 3) + (ch ^ 48) ;
ch = getchar () ;
}
flag ? x = -x : 0 ;
}
const int N = 1e5 + 7 ;
int n ,m ,a[N] ,b[N] ,q ,lgn[N] ,st1[N][25] ,st2[N][25] ;
struct segment_tree {
int l ,r ,Max ,Min ;
} t[N << 2] ,tt[N << 2] ;
#define l(cur) t[cur].l
#define r(cur) t[cur].r
#define Max(cur) t[cur].Max
#define Min(cur) t[cur].Min
namespace melo {
inline void pushup (int cur) {
Max (cur) = max (Max (ls) ,Max (rs)) ;
Min (cur) = min (Min (ls) ,Min (rs)) ;
}
inline void build (int cur ,int l ,int r) {
l (cur) = l ,r (cur) = r ;
if (l == r) {
Max (cur) = Min (cur) = b[l] ;
return ;
}
int mid = l + r >> 1 ;
melo :: build (ls ,l ,mid) ,melo :: build (rs ,mid + 1 ,r) ;
melo :: pushup (cur) ;
}
inline pair < int ,int > query (int cur ,int nowl ,int nowr) {
if (nowl <= l (cur) && nowr >= r (cur)) return make_pair (Max (cur) ,Min (cur)) ;
int mid = l (cur) + r (cur) >> 1 ;
pair < int ,int > ans ;
ans.first = -inf ,ans.second = inf ;
if (nowl <= mid && nowr >= l (cur)) {
ans.first = melo :: query (ls ,nowl ,nowr).first ;
ans.second = melo :: query (ls ,nowl ,nowr).second ;
} if (nowr > mid && nowl <= r (cur)) {
ans.first = max (ans.first ,melo :: query (rs ,nowl ,nowr).first) ;
ans.second = min (ans.second ,melo :: query (rs ,nowl ,nowr).second) ;
}
return ans ;
}
inline void pushup2 (int cur) {
tt[cur].Max = max (tt[ls].Max ,tt[rs].Max) ;
tt[cur].Min = min (tt[ls].Min ,tt[rs].Min) ;
}
inline void build2 (int cur ,int l ,int r) {
tt[cur].l = l ,tt[cur].r = r ;
if (l == r) {
tt[cur].Max = tt[cur].Min = a[l] ;
return ;
}
int mid = l + r >> 1 ;
melo :: build2 (ls ,l ,mid) ,melo :: build2 (rs ,mid + 1 ,r) ;
melo :: pushup2 (cur) ;
}
inline pair < int ,int > query2 (int cur ,int nowl ,int nowr) {
if (nowl <= tt[cur].l && nowr >= tt[cur].r) return make_pair (tt[cur].Max ,tt[cur].Min) ;
int mid = tt[cur].l + tt[cur].r >> 1 ;
pair < int ,int > ans ;
ans.first = -inf ,ans.second = inf ;
if (nowl <= mid && nowr >= tt[cur].l) {
ans.first = melo :: query2 (ls ,nowl ,nowr).first ;
ans.second = melo :: query2 (ls ,nowl ,nowr).second ;
} if (nowr > mid && nowl <= tt[cur].r) {
ans.first = max (ans.first ,melo :: query2 (rs ,nowl ,nowr).first) ;
ans.second = min (ans.second ,melo :: query2 (rs ,nowl ,nowr).second) ;
}
return ans ;
}
inline void pre () {
f (i ,1 ,lgn[n] ,1) {
f (j ,1 ,n - (1 << i) + 1 ,1) {
st1[j][i] = min (st1[j][i - 1] ,st1[j + (1 << i - 1)][i - 1]) ;
st2[j][i] = max (st2[j][i - 1] ,st2[j + (1 << i - 1)][i - 1]) ;
}
}
}
inline pair < int ,int > mm (int l ,int r) {
int lg = lgn[r - l + 1] ;
return make_pair (min (st1[l][lg] ,st1[r - (1 << lg) + 1][lg]) ,max (st2[l][lg] ,st2[r - (1 << lg) + 1][lg])) ;
}
}
signed main () {
read (n) ,read (m) ,read (q) ;
f (i ,1 ,n ,1) {
read(a[i]) ;
if (a[i] >= 0) {
st1[i][0] = a[i] ;
st2[i][0] = -inf ;
} else {
st2[i][0] = a[i] ;
st1[i][0] = inf ;
}
}
lgn[1] = 0 ;
f (i ,2 ,n ,1) lgn[i] = lgn[i >> 1] + 1 ;
f (i ,1 ,m ,1) read (b[i]) ;
melo :: build (1 ,1 ,m) ;
melo :: build2 (1 ,1 ,n) ;
melo :: pre () ;
while (q --) {
int l1 ,l2 ,r1 ,r2 ;
read (l1) ,read (r1) ,read (l2) ,read (r2) ;
pair < int ,int > c = melo :: query (1 ,l2 ,r2) ,d = melo :: query2 (1 ,l1 ,r1) ;
//cout << c.first << ' ' << c.second << ' ' << d.first << ' ' << d.second << '\n' ;
if (d.second >= 0) {
if (c.second >= 0) cout << d.first * c.second << '\n' ;
else cout << d.second * c.second << '\n' ;
} else if (d.first <= 0) {
if (c.first >= 0) cout << d.first * c.first << '\n ';
else cout << d.second * c.first << '\n' ;
} else {
pair < int ,int > res = melo :: mm (l1 ,r1) ;
//cout << "BUG" << res.first << ' ' << res.second << '\n' ;
int ans = -inf ;
if (c.second >= 0) ans = max (ans ,d.first * c.second) ;
else ans = max (ans ,res.first * c.second) ;
if (c.first >= 0) ans = max (ans ,res.second * c.first) ;
else ans = max (ans ,d.second * c.first) ;
cout << ans << '\n' ;
}
}
return 0 ;
}