news 2026/4/22 21:40:44

题解:P11540 [Code+ #5] 逻辑树

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
题解:P11540 [Code+ #5] 逻辑树

这是我 OI 生涯里见过的最难的黄题。

# 问题描述

给定一棵有根二叉树,包含 $2n-1$ 个节点,其中 $n$ 个叶子,每个叶子有一个真假值(True/False),每个非叶子点有一个运算符(AND 或 OR)。黑恶势力(以下简称黑)按照一个固定顺序 $p_i$ 询问叶子的值,但这个~~人工智能~~人会跳过不必要的询问(即当结果已确定时)。你需要:

1. 为每个叶子分配真假值,使得黑的询问次数尽到达最大值。
2. 在询问次数最多的前提下,使根节点的值为 True。

# 问题分析
1. 懒一点

1. AND 节点:当左子树为 False 时,不需要询问右子树。
2. OR 节点:当左子树为 True 时,不需要询问右子树。
2. 定义询问的次数:

1. 对于叶子,询问次数就是它在序列中的索引。
2. 对于非叶子点,询问次数取决于它子树的求值顺序和短路规则。
3. 防止 TLE:

1. 最大化整棵树的最终确定时间。
2. 在多个方案都能达到最大确定时间时,选择根为 True 的结果。

# 算法思路
对于每个节点 $u$,我们需要维护两个值:

## DP 法则
1. $f_u(0)$:以 $u$ 为根的子树,当 $u$ 的值为 False 时的最大确定时间。
2. $f_u(1)$:以 $u$ 为根的子树,当 $u$ 的值为 True 时的最大确定时间。

## 状态转移方程
设 $u$ 的两个子节点为 $a$ 和 $b$:

### 情况 1:$u$ 是 AND 节点
1. 当 $u = \text{False}$ 时:

- 情况 A:$a = \text{False}$,$b$ 任意。

- 确定时间 = $\min(f_a(0), \text{位置}(b))$(取较早判刑的一个)。
- 情况 B:$a = \text{True}$,$b = \text{False}$。

- 确定时间 = $f_b(0)$。
2. 当 $u = \text{True}$ 时:

- 必须 $a = \text{True}$ 且 $b = \text{True}$。
- 确定时间 = $\max(f_a(1), f_b(1))$(需要两个都为真才能确定)。

### 情况 2:$u$ 是 OR 节点
1. 当 $u = \text{False}$ 时:

- 必须 $a = \text{False}$ 且 $b = \text{False}$。
- 确定时间 = $\max(f_a(0), f_b(0))$。
2. 当 $u = \text{True}$ 时:

- 情况 A:$a = \text{True}$,$b$ 任意。

- 确定时间 = $\min(f_a(1), \text{位置}(b))$。
- 情况 B:$a = \text{False}$,$b = \text{True}$。

- 确定时间 = $f_b(1)$。

## 算法步骤
1. 初始化

- 对于叶子节点 $i$:$f_i(0) = f_i(1) = pos[i]$(在询问序列中的位置)。

2. 后序遍历:

- 从叶子向上计算每个节点的 $f_u(0)$ 和 $f_u(1)$。
- 记录达到最大确定时间时子节点的值选择。
3. 选择最优方案:

- 比较根节点的 $f_{root}(0)$ 和 $f_{root}(1)$。
- 优先判刑 $f_{root}(1)$(如果相等或更大)。
4. 回溯构造解:

- 从根节点开始,根据记录的选择向下分配叶子的值。



AC code

#include <bits/stdc++.h> using namespace std; const int maxnn = 1000005; int n, root; int op[maxnn]; int lc[maxnn], rc[maxnn]; int pos[maxnn]; int mt[maxnn][2]; int cl[maxnn][2], cr[maxnn][2]; vector<int> adj[maxnn]; void bt() {//这个题太BT了pwp root = n + 1; vector<int> parent(2*n, 0); stack<int> st; parent[root] = -1; st.push(root); while (!st.empty()) { int u = st.top(); st.pop(); int cnt = 0; for (int v : adj[u]) { if (v == parent[u]) continue; parent[v] = u; if (cnt == 0) lc[u] = v; else if (cnt == 1) rc[u] = v; cnt++; st.push(v); } } } int main() { scanf("%d", &n); for (int i = 1; i <= n-1; i++) { int v = n + i; scanf("%d", &op[v]); } for (int i = 0; i < 2*n-2; i++) { int u, v; scanf("%d%d", &u, &v); adj[u].push_back(v); adj[v].push_back(u); } bt(); for (int i = 1; i <= n; i++) { int leaf; scanf("%d", &leaf); pos[leaf] = i; } for (int i = 1; i <= n; i++) { mt[i][0] = mt[i][1] = pos[i]; } stack<pair<int,int>> st; st.push({root, 0}); while (!st.empty()) { int u = st.top().first; int state = st.top().second; st.pop(); if (u <= n) continue; if (state == 0) { st.push({u, 1}); if (rc[u]) st.push({rc[u], 0}); if (lc[u]) st.push({lc[u], 0}); } else { int a = lc[u], b = rc[u]; mt[u][0] = mt[u][1] = -1; for (int va = 0; va <= 1; va++) { for (int vb = 0; vb <= 1; vb++) { if (mt[a][va] == -1 || mt[b][vb] == -1) continue; int vu, tu; if (op[u] == 0) { vu = va & vb; if (va == 0 && vb == 0) tu = min(mt[a][va], mt[b][vb]); else if (va == 0 && vb == 1) tu = mt[a][va]; else if (va == 1 && vb == 0) tu = mt[b][vb]; else tu = max(mt[a][va], mt[b][vb]); } else { vu = va | vb; if (va == 1 && vb == 1) tu = min(mt[a][va], mt[b][vb]); else if (va == 1 && vb == 0) tu = mt[a][va]; else if (va == 0 && vb == 1) tu = mt[b][vb]; else tu = max(mt[a][va], mt[b][vb]); } if (tu > mt[u][vu]) { mt[u][vu] = tu; cl[u][vu] = va; cr[u][vu] = vb; } } } } } int rv; if (mt[root][1] >= mt[root][0]) rv = 1; else rv = 0; vector<int> ans(n+1, 0); stack<pair<int,int>> sa; sa.push({root, rv}); while (!sa.empty()) { int u = sa.top().first; int vu = sa.top().second; sa.pop(); if (u <= n) { ans[u] = vu; } else { int va = cl[u][vu]; int vb = cr[u][vu]; sa.push({rc[u], vb}); sa.push({lc[u], va}); } } for (int i = 1; i <= n; i++) { printf("%d", ans[i]); } printf("\n"); return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 12:22:12

Qwen3-VL集群部署:多GPU并行推理优化

Qwen3-VL集群部署&#xff1a;多GPU并行推理优化 1. 引言&#xff1a;Qwen3-VL-WEBUI 的工程落地背景 随着多模态大模型在视觉理解、图文生成和智能代理等场景的广泛应用&#xff0c;高效部署具备强大视觉-语言能力的模型成为AI工程化的重要挑战。阿里云开源的 Qwen3-VL-WEBU…

作者头像 李华
网站建设 2026/4/18 14:06:08

绝区零一条龙:免费自动化工具终极使用指南

绝区零一条龙&#xff1a;免费自动化工具终极使用指南 【免费下载链接】ZenlessZoneZero-OneDragon 绝区零 一条龙 | 全自动 | 自动闪避 | 自动每日 | 自动空洞 | 支持手柄 项目地址: https://gitcode.com/gh_mirrors/ze/ZenlessZoneZero-OneDragon 绝区零一条龙是一款专…

作者头像 李华
网站建设 2026/4/3 8:45:44

BetterNCM安装器:让网易云音乐功能更强大的秘密武器

BetterNCM安装器&#xff1a;让网易云音乐功能更强大的秘密武器 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 想要让网易云音乐变得更加好用吗&#xff1f;BetterNCM安装器就是你的不…

作者头像 李华
网站建设 2026/4/23 11:14:52

一文说清模拟电子技术中的共射极放大器原理

深入理解共射极放大器&#xff1a;从原理到实战设计在模拟电路的世界里&#xff0c;如果说晶体管是“心脏”&#xff0c;那么共射极放大器&#xff08;Common-Emitter Amplifier&#xff09;就是这颗心脏最有力的一次搏动。它不仅是双极结型晶体管&#xff08;BJT&#xff09;三…

作者头像 李华
网站建设 2026/4/10 18:12:59

NSudo权限管理工具完全指南:从基础使用到高级技巧

NSudo权限管理工具完全指南&#xff1a;从基础使用到高级技巧 【免费下载链接】NSudo [Deprecated, work in progress alternative: https://github.com/M2Team/NanaRun] Series of System Administration Tools 项目地址: https://gitcode.com/gh_mirrors/nsu/NSudo NS…

作者头像 李华
网站建设 2026/4/18 10:54:19

GRBL全面讲解:常见主板引脚定义与接线设置

GRBL引脚全解析&#xff1a;从接线“踩坑”到精准控制的实战指南你有没有遇到过这样的情况&#xff1f;辛辛苦苦搭好CNC雕刻机&#xff0c;上传G代码后电机“咔哒”一声就停了&#xff1b;主轴明明发了启动指令却毫无反应&#xff1b;回零时轴直接撞到极限位置发出刺耳摩擦声……

作者头像 李华