[CSP-S 2022] 策略游戏
[CSP-S 2022] 策略游戏
题目分析#
本文中 A 和 B 分别代表小 L 和小 Q,而原题中的
矩阵这个描述就是障眼法。翻译一下题目:
A 在
肯定先思考 B 再思考 A,因为 A 会思考 B 的思考。
B 的行为就是对于
具体地:
时,B 会选择最小的 ; 时,B 会选择最大的 。
那么 A 的行为是什么呢?还是按照正负分类讨论:
如果 A 这次想让
如果 A 这次想让
因此 A 的行为只有四种:选择最大的
分别讨论 A 选择四种行为时 B 的选择,答案取最大值即可。
然后就变成了静态区间最值的板子。使用 6 个 ST 表分别存储以下信息:
的区间最大值; 的区间最小值; 的负数区间最大值;- 具体是把所有满足
的 全部替换为 代表这个位置不存在数,至于为何是 请读者自己思考。
- 具体是把所有满足
的非负数区间最小值;- 具体是把所有满足
的 全部替换为 代表这个位置不存在数。
- 具体是把所有满足
的区间最大值; 的区间最小值。
时间复杂度
代码实现#
#include <bits/stdc++.h>
#define rint register int
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e5 + 5;
const int M = 2e1 + 1;
const int maxinf = 1e18;
const int mininf = -1e18;
int n, m, q;
int maxx1[N][M], minn1[N][M];
int maxx2[N][M], minn2[N][M];
int maxx3[N][M], minn3[N][M];
int query_min(int l, int r, int *a)
{
int k = log2(r - l + 1);
return min(a[l * M + k], a[(r - (1 << k) + 1) * M + k]);
}
int query_max(int l, int r, int *a)
{
int k = log2(r - l + 1);
return max(a[l * M + k], a[(r - (1 << k) + 1) * M + k]);
}
// maxx1: a 的区间最大值, minn1: a 的区间最小值
// maxx2: a 的负数区间最大值, minn2: a 的非负数区间最小值。
// maxx3: b 的区间最大值, minn3: b 的区间最小值。
signed main()
{
cin >> n >> m >> q;
for (rint i = 1; i <= n; i++)
{
int k;
cin >> k;
maxx1[i][0] = minn1[i][0] = k;
maxx2[i][0] = (k < 0 ? k : mininf);
minn2[i][0] = (k >= 0 ? k : maxinf);
}
for (rint i = 1; i <= m; i++)
{
int k;
cin >> k;
maxx3[i][0] = k;
minn3[i][0] = k;
}
for (rint j = 1; j <= 21; j++)
{
for (rint i = 1; i + (1 << j) - 1 <= n; ++i)
{
int k = i + (1 << (j - 1));
maxx1[i][j] = max(maxx1[i][j - 1], maxx1[k][j - 1]);
maxx2[i][j] = max(maxx2[i][j - 1], maxx2[k][j - 1]);
minn1[i][j] = min(minn1[i][j - 1], minn1[k][j - 1]);
minn2[i][j] = min(minn2[i][j - 1], minn2[k][j - 1]);
}
}
for (rint j = 1; j <= 21; j++)
{
for (rint i = 1; i + (1 << j) - 1 <= m; i++)
{
int k = i + (1 << (j - 1));
maxx3[i][j] = max(maxx3[i][j - 1], maxx3[k][j - 1]);
minn3[i][j] = min(minn3[i][j - 1], minn3[k][j - 1]);
}
}
while (q--)
{
int l1, r1, l2, r2;
cin >> l1 >> r1 >> l2 >> r2;
int amax = query_max(l1, r1, (int *)maxx1);
int amin = query_min(l1, r1, (int *)minn1);
int afmx = query_max(l1, r1, (int *)maxx2);
int afmn = query_min(l1, r1, (int *)minn2);
int bmax = query_max(l2, r2, (int *)maxx3);
int bmin = query_min(l2, r2, (int *)minn3);
int ans = mininf;
ans = max(ans, amax * (amax >= 0 ? bmin : bmax));
ans = max(ans, amin * (amin >= 0 ? bmin : bmax));
if (afmx != mininf)
{
ans = max(ans, afmx * (afmx >= 0 ? bmin : bmax));
}
if (afmn != maxinf)
{
ans = max(ans, afmn * (afmn >= 0 ? bmin : bmax));
}
cout << ans << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】