https://www.luogu.com.cn/problem/P8818
代码
#include <bits/stdc++.h>
#define int long long
using type_a4 = std::array<int, 4>;
const int N = 1e5 + 10, INF = 9e9;
int n, m, q, a[N], b[N];
struct SegmentTree {
int w[N << 2], zmax[N << 2], zmin[N << 2], fmax[N << 2], fmin[N << 2];
bool inRange(int l, int r, int L, int R) {
return l >= L && r <= R;
}
bool outRange(int l, int r, int L, int R) {
return l > R || r < L;
}
void pushup(int u) {
zmax[u] = std::max(zmax[u << 1], zmax[u << 1 | 1]);
zmin[u] = std::min(zmin[u << 1], zmin[u << 1 | 1]);
fmax[u] = std::max(fmax[u << 1], fmax[u << 1 | 1]);
fmin[u] = std::min(fmin[u << 1], fmin[u << 1 | 1]);
}
type_a4 pushup(type_a4 x, type_a4 y) {
type_a4 res;
res[0] = std::max(x[0], y[0]);
res[1] = std::min(x[1], y[1]);
res[2] = std::max(x[2], y[2]);
res[3] = std::min(x[3], y[3]);
return res;
}
void build(int *a, int u, int l, int r) {
if (l == r) {
w[u] = a[l];
if (w[u] >= 0) {
zmax[u] = zmin[u] = w[u];
fmax[u] = -INF;
fmin[u] = INF;
} else {
zmax[u] = -INF;
zmin[u] = INF;
fmax[u] = fmin[u] = w[u];
}
return ;
}
int mid = l + r >> 1;
build(a, u << 1, l, mid);
build(a, u << 1 | 1, mid + 1, r);
pushup(u);
}
// 返回值依次返回 zmax, zmin, fmax, fmin
type_a4 query(int u, int l, int r, int L, int R) {
if (outRange(l, r, L, R)) return type_a4({-INF, INF, -INF, INF});
if (inRange(l, r, L, R)) return type_a4({zmax[u], zmin[u], fmax[u], fmin[u]});
int mid = l + r >> 1;
return pushup(query(u << 1, l, mid, L, R), query(u << 1 | 1, mid + 1, r, L, R));
}
} ta, tb;
signed main() {
std::cin.tie(0)->sync_with_stdio(0);
std::cin >> n >> m >> q;
for (int i = 1; i <= n; ++i) std::cin >> a[i];
for (int i = 1; i <= m; ++i) std::cin >> b[i];
ta.build(a, 1, 1, n), tb.build(b, 1, 1, m);
for (int l1, r1, l2, r2; q; --q) {
std::cin >> l1 >> r1 >> l2 >> r2;
auto x = ta.query(1, 1, n, l1, r1);
auto y = tb.query(1, 1, m, l2, r2);
if (abs(y[0]) != INF && abs(y[2]) != INF) { // 后手有正有负
std::cout << std::max(x[1] * y[3], x[2] * y[0]) << '\n';
} else if (abs(y[0]) != INF) { // 后手只有正数
if (abs(x[0]) != INF) { // 先手有正数
std::cout << x[0] * y[1] << '\n';
} else { // 先手只有负数
std::cout << x[2] * y[0] << '\n';
}
} else { // 后手只有负数
if (abs(x[2]) != INF) { // 先手有负数
std::cout << x[3] * y[2] << '\n';
} else { // 先手只有正数
std::cout << x[1] * y[3] << '\n';
}
}
}
std::cout.flush();
return 0;
}
一个神奇的事情是,分数与 INF
相关,但是当 INF
达到 9\times10^9+2\times10^8 左右的时候,会 WA 更多的点。
求调/kel