士兵训练 题解

news/2024/10/8 14:28:00/文章来源:https://www.cnblogs.com/zphh/p/18451550

题意

link.

题解

正解会 RE 几个点,是官方的栈空间太小了。

再者网上几篇题解都被我 hack 了,好不容易找到一组 hack 却不是我错了,而是 STD 错了……

所以我来写篇题解造福社会。


观察到 \(\max \{b_i \bmod b_j\}\),则得到的结果一定比最大值小,则最大能取到次大。

那就维护一个子树内的最大、次大记为 \(bmax\)\(b\_max\)

但是我们需要在外面加一个 \(l\)

似乎再维护一个子树外最大 \(l\) 就行了。

但是不对。

如果是只维护一个最大 \(lmax\)

\[ \left\{ \begin{array}llmax + b\_max > bmax, ~bmax\\ lmax + b\_max < bmax, ~lmax + b\_max\\ lmax + b\_max = bmax, ? \end{array} \right. \]

此时问号情况就无法维护。

所以还要维护一个次大 \(l\_max\)
(并且严格、不为零,否则就白维护了);

\[ \left\{ \begin{array} llmax + b\_max > bmax, ~bmax\\ lmax + b\_max < bmax, ~lmax + b\_max\\ lmax + b\_max = bmax, ~b\_max + l\_max \end{array} \right. \]

但此时还是不对,因为第三种情况还需要考虑到次次大,因此还需要维护一个严格的次次大 \(b\_\_max\)

\[ \left\{ \begin{array} llmax + b\_max > bmax, ~bmax\\ lmax + b\_max < bmax, ~lmax + b\_max\\ lmax + b\_max = bmax, ~\min(b\_max + l\_max, b\_\_max + lmax) \end{array} \right. \]

但,还没完。

如果有 \(b\_max = bmax\) 的情况……虽然有,但显然不够优,就不用考虑啦。

完结撒花。

只不过维护 \(lmax\)\(l\_max\) 的同时还要再维护一个 \(lmax\_\)\(lmax\_\_\),表示子树内的最大值然后转移得到 \(lmax\)

非常恶心,真的要看吗。


namespace zqh {const int N = 200005;int n, q, fa[N];vector<int> g[N];struct node {int bmax;int b_max;int b__max;int lmax, l_max, l__max, lmax_;int fht, tch;node() {bmax = b__max = b_max = -1;fht = tch = lmax = l_max = l__max = lmax_ = 0;}} b[N];void dfs(int u) {if (!u) return;if (g[u].empty()) {b[u].bmax = b[u].fht;b[u].lmax = b[u].tch;return;}vector<int> q, p;
//		cout << "hmz AK IOI\n";q.push_back(b[u].fht);for (int x : g[u]) {dfs(x);q.push_back(b[x].bmax);q.push_back(b[x].b_max);q.push_back(b[x].b__max);p.push_back(b[x].lmax);p.push_back(b[x].lmax_);}p.push_back(b[u].tch);sort(p.begin(), p.end(), greater<int>());sort(q.begin(), q.end(), greater<int>());b[u].bmax = q[0];b[u].b_max = q[1];for (int i = 2; i < q.size(); i++)if (q[i] != q[1]) {b[u].b__max = q[i];break;}b[u].lmax = p[0];b[u].lmax_ = p[1];for (int i = 1; i < p.size(); i++){if (p[i] != b[u].lmax){b[u].lmax_ = p[i];break;}}}int get_l_max(int u) {if (b[u].l_max) return b[u].l_max;if (u == 1) {return b[u].l_max = 0;}int t = fa[u];int ans = b[t].tch;for (int x : g[t]) {if (x == u) continue;ans = max(ans, b[x].lmax);ans = max(ans, b[x].lmax_);}b[u].l_max = max(ans, get_l_max(t));return b[u].l_max;}int get_l__max(int u) {if (b[u].l__max) return b[u].l__max;if (u == 1) {return b[u].l__max = 0;}int t = fa[u];vector<int> q;q.push_back(b[t].tch);for (int x : g[t]) {if (x == u) continue;q.push_back(b[x].lmax);q.push_back(b[x].lmax_);
//			ans = max(ans, b[x].lmax);}q.push_back(b[t].l_max);q.push_back(get_l__max(t));sort(q.begin(), q.end(), greater<int>());for (int i = 0; i < q.size(); i++) {if (q[i] != b[u].l_max) {b[u].l__max = q[i];break;}}
//		b[u].l__max = q[1];return b[u].l__max;}void calc_l_max() {rep (i, 1, n) {if (g[i].empty())get_l_max(i);}}void calc_l__max() {rep (i, 1, n) {if (g[i].empty())get_l__max(i);}}int dfs3(int u, int max_) {int ans = 0;if (b[u].fht != max_) {ans = b[u].fht;}for (int x : g[u]) {ans = max(ans, dfs3(x, max_));}return ans;}void init() {cin >> n >> q;rep (i, 2, n) {cin >> fa[i];g[fa[i]].push_back(i);}rep (i, 1, n) {cin >> b[i].fht >> b[i].tch;}}void solve() {dfs(1);calc_l_max();calc_l__max();rep (i, 1, n) {if (b[i].l__max > b[i].l_max) swap(b[i].l__max, b[i].l_max);if (b[i].lmax_ > b[i].lmax) swap(b[i].lmax_, b[i].lmax);}// rep (i, 460, 460) {// cout << b[i].bmax << " " << b[i].b_max << " " << b[i].b__max << " " << b[i].l_max << " " << b[i].l__max << endl;// }//4053 3053 2016 //1000 990// q = 0;while (q--) {int s;cin >> s;
//			cout << "[" << b[s].bmax << " " << b[s].b_max << " " << b[s].b__max << "]\n";int l = b[s].l_max;
//			cout << l << endl;if (b[s].b_max == -1) {cout << "0\n";continue;}
// if (l == 0 && b[s].bmax == b[s].b_max) {
// cout << dfs3(s, b[s].bmax) << endl;
// continue;
// }if (l + b[s].b_max > b[s].bmax) {cout << b[s].bmax << endl;continue;}if (l + b[s].b_max < b[s].bmax) {cout << l + b[s].b_max << endl;continue;}
// if (b[s].b__max == -1) {
// cout << max(b[s].b_max + b[s].l__max, 0LL) << endl;
// continue;
// }
//			cout << b[s].l__max << endl;if (b[s].b__max != b[s].b_max) {int ans = 0;if (b[s].l_max + b[s].b__max < b[s].bmax && b[s].b__max != -1)ans = max(ans, b[s].l_max + b[s].b__max);if (b[s].l__max + b[s].b_max < b[s].bmax && b[s].b_max != -1)ans = max(ans, b[s].l__max + b[s].b_max);cout << ans << endl;}
//				while(1);
//				cout << min(b[s].bmax, b[s].b_max + b[s].l__max) << endl;
//			}}}void main() {init();solve();}
}  // namespace zqh

赛时 80,后面死活 95 分,心态崩了。

后面才终于调对了。

最后的最后,提供几组 hack,还要可以私信。

10 10
1 1 1 1 3 3 6 4 1 7 1
7 0
1 7
3 5
7 5
1 2
5 5
2 7
7 3
6 0
1
2
3
4
5
6
7
8
9
10
5
0
5
7
0
2
0
0
0
0

5
1 2 2 1
7 6
9 6
0 1
0 8
8 2
1
2
3
4
5
8
9
0
0
0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809949.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day02_基本的DOS命令

电脑常用快捷键 常用快捷键快捷键 作用CTRL + c 复制CTRL + v 粘贴CTRL + x 剪切CTRL + z 撤销CTRL + s 保存alt + f4 关闭窗口del 删除shift + del 强制删除Windows + r 打开 “运行” 窗口windows + e 打开 “我的文档”ctrl + alt + del 锁定/切换用户/注销/更改密码/任务管…

组态也能开发WEB前端 | uiotos致敬amis、nodered、appsmith、codewave、goview、dataroom、iotrouter、FUXA、乐吾乐

WEB组态开发SCADA、HMI画面、大屏可视化,还比较常见。比如下面: UIOTOS组态示例 那么常规WEB前端功能,组态能否一并做了呢?比如下面这种: UIOTOS前端示例 答案是可以的!UIOTOS支持页面无限嵌套,能实现原型即应用。现在就以一个具体小示例介绍如何实现的。 效果 如下所示…

GUI无代码小示例 - 工作流连线实现0/1连续翻转

效果 如下所示,连续点击按钮,输出0、1、0、1...。 步骤新建页面,拖入组件拖入3个组件:数学计算、输入框、按钮。如下所示: 连线和配置按钮点击 → 函数执行1减去输入,作为函数输出这样,当首次执行时,默认操作数1将减去输入的1,输出0。 函数输出→ 输入框 → 函数输入 …

Java生成条形码(亲测可通过扫码枪扫出)

Java生成条形码(亲测可通过扫码枪扫出) 秃秃爱健身该博客介绍了如何在Java项目中通过barcode4j库生成Code128条形码,解决了条形码扫不出或美观度不足的问题。提供了相关代码示例,包括Maven依赖、工具类和生成条形码的方法,可以自定义条形码的高度、宽度、是否留白和隐藏文…

点“亮”户外应用场景,来看触想高亮显示器TPC-M8的硬实力!

工业显示器作为信息可视化和人机交互的重要媒介,正在越来越多领域担当关键任务,工业显示器的可读性及耐用性,影响应用体验、设备安全和生产效率。尤其在户外,面对高低温、灰尘雨水、强光紫外线等极端因素,常规性能的工业显示器已不足以覆盖户外高风险应用需求。为此,触想…

phpvulhunter工具:静态 php 代码审计

phpvulhunter是一款PHP源码自动化审计工具,通过这个工具,可以对一些开源CMS进行自动化的代码审计,并生成漏洞报告。 1、安装 首先从github上进行获取: git clone https://github.com/OneSourceCat/phpvulhunter2、下载完成后,将工程目录放置于 WAMP 等 PHP-Web 运行环境中…

YOLOv8-seg训练与推理

1.YOLOv8-seg简介 YOLOv8-seg是YOLO系列模型的其中一个版本。YOLOv8-seg在继承YOLO系列模型高效性和准确性的基础上,增加了实例分割的能力。 2.数据集使用的数据集较简单,主要以下目录:images:存放原始图片(1500张),大小为128x128。部分如下: images_json:存放labelme标注的…

易基因: cfMeDIP-seq揭示cfDNA甲基化高效区分原发性和转移性前列腺|Nat Commun

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 前列腺癌(Prostate cancer,PCa)是男性中第二常见的恶性肿瘤,也是全球癌症相关死亡的第三大原因。虽然大多数原发性前列腺癌可以治愈,但转移性前列腺癌患者的5年生存率仍低至30%。大多数患者很快就会发展成…

从零搭建Xswitch进行测试

1 xswitch官网 拉取社区版xwitch docker镜像,编译之,修改.env文件 ,把docker跑起来,这个是核心服务 跑起来如下,端口映射不需要管,他内部做好的,默认sip使用7060 前端ws连接端口 8081 wss连接端口 8082 2 自己照着官网ES6 demo 例子写 Vetro 例子,我是用的vue搞的前端…

【日记】医生拆线居然还能没拆干净(1796 字)

正文早上拆线,医院的门诊登记簿上写名字排队。我前面人还挺多。不过医生问过前面的情况之后,就先给我做了,因为拆线快。等我到市里转车,吃过饭后才发现,那个医生拆线没拆干净…… 吃了饭感觉口腔里还是有奇怪的东西,那个粗糙的质感,确定是线头没错了……找了个酒店的卫生…

Docker 学习笔记-基本概念与安装

Docker 学习笔记 基本概念镜像:Docker 的镜像概念类似于虚拟机里的镜像,是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。 DockerFile;镜像可以基于 DockerFile 构建,DockerFile 是一个描述文件,里面包含若干条命令,每条命令都会对…

面相快速入门教程7木型

7 木型 在本章中,我将介绍木型的基础知识,你将学会如何识别木型。首先,我们来快速参考一下木的特征:能量:向上、推动、活跃、早晨、春天、童年 特质:乐观、热情、活跃、人道主义、自信、愤怒、沮丧、冲动、反应灵敏、直接、敏锐、实际、逻辑性强、有条理、果断、有判断力…