当前位置: 首页 > java >正文

2022 CCF CSP-S2.策略游戏

题目

4733. 策略游戏
在这里插入图片描述

算法标签: S T ST ST表, 线段树

思路

可以求每一行的最小值, 第一个人从每一行最小值选择最大的一个, 但是行和列的数量是 1 0 5 10 ^ 5 105级别, 因此不能直接创建矩阵进行维护, 当第一个人选定某一行 x x x后确定了, 但是 B B B希望选择最小的, 需要考虑 A x A_x Ax正负性, 如果 A x A_x Ax是正数, 需要在 B y B_y By中选择最小值, 目标值是 B m i n × A x B_{min} \times A_x Bmin×Ax, 对于第一个人来说, 如果想要求最大值, 还需要分析 B m i n B_{min} Bmin正负性

在这里插入图片描述

总结来说对于如果 A x A_x Ax的所有取值都是正数数, 因为 A A A是绝顶聪明的, 是知道 B B B取最小值的, 因此对于 A A A来说最后的得分需要取决于 B m i n B_{min} Bmin的正负性

如果第一个人从负数里面选, 因为 A A A是决定聪明的, 因此是知道第二个人一定取值是 B m a x B_{max} Bmax, 还是取决于 B m a x B_{max} Bmax的正负性

将问题总结为

  • A A A的某个区间的非负整数的最小值
  • A A A的某个区间的非负整数的最大值
  • A A A的某个区间负数的最小值
  • A A A的某个区间负数的最大值
  • B B B的某个区间的最小值
  • B B B的某个区间的最大值

直接开 6 6 6个线段树或者 S T ST ST表求解

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>using namespace std;typedef long long LL;
const int N = 100010, INF = 2e9 + 10;
const LL LL_INF = 5e18;int n, m, q;
int a[N], b[N];
struct Node {int l, r, val;
} tr[6][N << 2];int get(int u, int type) {if (type == 0) return a[u] >= 0 ? a[u] : INF;      // A中非负的最小值if (type == 1) return a[u] >= 0 ? a[u] : -INF;     // A中非负的最大值if (type == 2) return a[u] < 0 ? a[u] : INF;       // A中负数的最小值if (type == 3) return a[u] < 0 ? a[u] : -INF;      // A中负数的最大值return b[u];                                       // B数组的值
}void push_up(Node tr[], int u, int type) {int l_val = tr[u << 1].val, r_val = tr[u << 1 | 1].val;// 偶数求最小值if (type % 2 == 0) tr[u].val = min(l_val, r_val);// 奇数求最大值else tr[u].val = max(l_val, r_val);
}void build(Node tr[], int u, int l, int r, int type) {tr[u] = {l, r};if (l == r) {tr[u].val = get(r, type);return;}int mid = l + r >> 1;build(tr, u << 1, l, mid, type);build(tr, u << 1 | 1, mid + 1, r, type);push_up(tr, u, type);
}int query(Node tr[], int u, int ql, int qr, int type) {if (tr[u].l >= ql && tr[u].r <= qr) return tr[u].val;int mid = tr[u].l + tr[u].r >> 1;// 查询最小值if (type % 2 == 0) {int ans = INF;if (ql <= mid) ans = min(ans, query(tr, u << 1, ql, qr, type));if (qr > mid) ans = min(ans, query(tr, u << 1 | 1, ql, qr, type));return ans;}// 查询最大值int ans = -INF;if (ql <= mid) ans = max(ans, query(tr, u << 1, ql, qr, type));if (qr > mid) ans = max(ans, query(tr, u << 1 | 1, ql, qr, type));return ans;
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);cin >> n >> m >> q;for (int i = 1; i <= n; ++i) cin >> a[i];for (int i = 1; i <= m; ++i) cin >> b[i];for (int i = 0; i < 4; ++i) build(tr[i], 1, 1, n, i);for (int i = 4; i < 6; ++i) build(tr[i], 1, 1, m, i);while (q--) {int l1, r1, l2, r2;cin >> l1 >> r1 >> l2 >> r2;// 查询B数组的最小值和最大值int y_min = query(tr[4], 1, l2, r2, 4);int y_max = query(tr[5], 1, l2, r2, 5);LL x, ans = -LL_INF;// B的最小值非负时,A应选择最大的非负数if (y_min >= 0) x = query(tr[1], 1, l1, r1, 1);else x = query(tr[0], 1, l1, r1, 0);if (abs(x) != INF) ans = max(ans, x * (LL)y_min);// B的最大值非负时,A应选择最大的负数if (y_max >= 0) x = query(tr[3], 1, l1, r1, 3);else x = query(tr[2], 1, l1, r1, 2);if (abs(x) != INF) ans = max(ans, x * (LL)y_max);cout << ans << "\n";}return 0;
}
http://www.xdnf.cn/news/725.html

相关文章:

  • Transformer系列(一):NLP中放弃使用循环神经网络架构
  • xss4之cookie操作
  • SpringBoot Actuator指标收集:Micrometer与Prometheus集成
  • 【网络篇】从零写UDP客户端/服务器:回显程序源码解析
  • 基于kubernetes1.23.17容器化部署RuoYi全栈项目手册
  • AI与思维模型【69】——人类误判心理
  • 计算机视觉与深度学习 | TensorFlow基本概念与应用场景:MNIST 手写数字识别(附代码)
  • 洛谷题目:P7775 [COCI 2009/2010 #2] VUK 题解 (本题简)
  • 雨滴传感器详解(STM32)
  • spring事务
  • C++ 模块化编程(Modules)在大规模系统中的实践难点
  • Spring Boot 集成 Kafka 及实战技巧总结
  • 计算机视觉cv入门之Haarcascade的基本使用方法(人脸识别为例)
  • 内存管理详解(曼波脑图超详细版!)
  • 物联网技术赋能:复杂环境下的能源数据零丢失
  • 【小沐杂货铺】基于Three.JS绘制卫星轨迹Satellite(GIS 、WebGL、vue、react,提供全部源代码)
  • LeetCode 每日一题 2563. 统计公平数对的数目
  • Apache Parquet 文件组织结构
  • Redis 哨兵与集群脑裂问题详解及解决方案
  • 声音识别(声纹识别)和语音识别的区别
  • Linux 下依赖库的问题
  • (4)Vue的生命周期详细过程
  • 力扣每日一题781题解-算法:贪心,数学公式 - 数据结构:哈希
  • windows服务器及网络:论如何安装(虚拟机)
  • 无意间发现的宝藏项目:开源世界中的演示项目精选合集
  • 爬虫学习——Spider和Selector
  • 快速下载Node.js
  • 【计算机网络 | 第三篇】常见的网络协议(二)
  • 山东大学软件学院创新项目实训开发日志(20)之中医知识问答自动生成对话标题bug修改
  • 使用 Selenium 进行 Web 自动化:详细操作指南