CSP-S 2022 策略游戏
RMQ,贪心
因为 \(-10^9 \leq A_i, B_i \leq 10^9\),而且要相乘,所以我们需要分类讨论。
设 \(\max_1, \min_1\) 表示正整数的最大值、最小值,\(\max_2, \min_2\) 表示负整数的最大值、最小值。
分类讨论,则
| A 选 | B 选 |
|---|---|
| \(\max_1 A, \min_1 A\) | \(\min_1 B, \min_2 B\) |
| \(\max_2 A, \min_2 A\) | \(\max_1 B, \max_2 B\) |
B 选中优先选择第一个,如果不存在考虑第二个。思考后可得 \(0\) 在这里既要算作正整数,也要算作负整数。
为了让代码更简单,可以把这四个值记录下来,分别记作 \(X_i, Y_i\),\(4 \times 4\) 枚举一遍,则答案为 \(\max \min {X_i \times Y_j}\)。注意,不存在的情况不能计算。
使用线段树实现或 ST 表实现,时间复杂度都为 \(O(n \log n)\)。(考虑到 \(n, m, q\) 上限相同)
#include <bits/stdc++.h>
typedef long long LL;
const int N = 100005, inf = 2e9;
struct Info {
int l, r;
int pmax, pmin; // 正数
int qmax, qmin; // 负数
};
int A[N], B[N];
struct SegmentTree {
Info t[N * 4];
bool ini;
void init(int x) {
ini = x;
}
#define lson p * 2
#define rson p * 2 + 1
void pushup(int p) {
t[p].pmax = std::max(t[lson].pmax, t[rson].pmax);
t[p].pmin = std::min(t[lson].pmin, t[rson].pmin);
t[p].qmax = std::max(t[lson].qmax, t[rson].qmax);
t[p].qmin = std::min(t[lson].qmin, t[rson].qmin);
}
void build(int p, int l, int r) {
t[p].l = l, t[p].r = r;
if (l == r) {
int x = ini ? A[l] : B[l];
if (x >= 0) {
t[p].pmax = x, t[p].pmin = x;
t[p].qmax = -inf, t[p].qmin = inf;
}
if (x <= 0) {
t[p].pmax = -inf, t[p].pmin = inf;
t[p].qmax = x, t[p].qmin = x;
}
return;
}
int mid = (l + r) / 2;
build(lson, l, mid);
build(rson, mid + 1, r);
pushup(p);
}
int queryPmax(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r) return t[p].pmax;
int mid = (t[p].l + t[p].r) / 2;
int ans = -inf;
if (l <= mid) ans = std::max(ans, queryPmax(lson, l, r));
if (r > mid) ans = std::max(ans, queryPmax(rson, l, r));
return ans;
}
int queryPmin(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r) return t[p].pmin;
int mid = (t[p].l + t[p].r) / 2;
int ans = inf;
if (l <= mid) ans = std::min(ans, queryPmin(lson, l, r));
if (r > mid) ans = std::min(ans, queryPmin(rson, l, r));
return ans;
}
int queryQmax(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r) return t[p].qmax;
int mid = (t[p].l + t[p].r) / 2;
int ans = -inf;
if (l <= mid) ans = std::max(ans, queryQmax(lson, l, r));
if (r > mid) ans = std::max(ans, queryQmax(rson, l, r));
return ans;
}
int queryQmin(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r) return t[p].qmin;
int mid = (t[p].l + t[p].r) / 2;
int ans = inf;
if (l <= mid) ans = std::min(ans, queryQmin(lson, l, r));
if (r > mid) ans = std::min(ans, queryQmin(rson, l, r));
return ans;
}
#undef lson
#undef rson
} seg1, seg2;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, m, q;
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];
seg1.init(1);
seg2.init(0);
seg1.build(1, 1, n);
seg2.build(1, 1, m);
for (int i = 1; i <= q; i++) {
int l1, r1, l2, r2;
std::cin >> l1 >> r1 >> l2 >> r2;
int X[4], Y[4];
X[0] = seg1.queryPmax(1, l1, r1);
X[1] = seg1.queryPmin(1, l1, r1);
X[2] = seg1.queryQmax(1, l1, r1);
X[3] = seg1.queryQmin(1, l1, r1);
Y[0] = seg2.queryPmax(1, l2, r2);
Y[1] = seg2.queryPmin(1, l2, r2);
Y[2] = seg2.queryQmax(1, l2, r2);
Y[3] = seg2.queryQmin(1, l2, r2);
LL ans = -1e18;
for (int i = 0; i < 4; i++) {
if (X[i] == inf || X[i] == -inf)
continue;
LL res = 1e18;
for (int j = 0; j < 4; j++) {
if (Y[j] == inf || Y[j] == -inf)
continue;
res = std::min(res, 1ll * X[i] * Y[j]);
}
ans = std::max(ans, res);
}
std::cout << ans << '\n';
}
return 0;
}

浙公网安备 33010602011771号