只是单纯晒晒两天才攻克的线段树代码(y总式码风真的优美)
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010, INF = 0x3f3f3f3f;
typedef long long LL;
struct Tree
{
int l, r;
int maxz, minz, maxf, minf;
}tr1[N * 4], tr2[N * 4];
int n, m, q;
int a[N], b[N];
void pushup(Tree &p, Tree &l, Tree &r)
{
p.maxz = max(l.maxz, r.maxz);
p.minz = min(l.minz, r.minz);
p.maxf = max(l.maxf, r.maxf);
p.minf = min(l.minf, r.minf);
}
void build(Tree tr[], int w[], int p, int l, int r)
{
if (l == r)
{
tr[p] = {l, r, -INF, INF, -INF, INF};
if (w[r] >= 0) tr[p].maxz = tr[p].minz = w[r];
if (w[r] <= 0) tr[p].maxf = tr[p].minf = w[r];
return;
}
tr[p] = {l, r};
int mid = l + r >> 1;
build(tr, w, p << 1, l, mid), build(tr, w, p << 1 | 1, mid + 1, r);
pushup(tr[p], tr[p << 1], tr[p << 1 | 1]);
}
Tree query(Tree tr[], int p, int l, int r)
{
if (l <= tr[p].l && r >= tr[p].r) return tr[p];
else
{
int mid = tr[p].l + tr[p].r >> 1;
if (l > mid) return query(tr, p << 1 | 1, l, r);
if (r <= mid) return query(tr, p << 1, l, r);
Tree res, L = query(tr, p << 1, l, r), R = query(tr, p << 1 | 1, l, r);
pushup(res, L, R);
return res;
}
}
int main()
{
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for (int i = 1; i <= m; i ++ ) scanf("%d", &b[i]);
build(tr1, a, 1, 1, n), build(tr2, b, 1, 1, m);
while (q -- )
{
int l1, r1, l2, r2;
scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
Tree t1 = query(tr1, 1, l1, r1), t2 = query(tr2, 1, l2, r2);
LL res;
if (t2.minf == INF)
{
if (t1.minz != INF) res = (LL)t1.maxz * t2.minz;
else res = (LL)t1.maxf * t2.maxz;
}
else if (t2.minz == INF)
{
if (t1.minf != INF) res = (LL)t1.minf * t2.maxf;
else res = (LL)t1.minz * t2.minf;
}
else
{
if (t1.minz == INF) res = (LL)t1.maxf * t2.maxz;
else if (t1.minf == INF) res = (LL)t1.minz * t2.minf;
else res = max((LL)t1.maxf * t2.maxz, (LL)t1.minz * t2.minf);
}
printf("%lld\n", res);
}
return 0;
}