洛谷 P7011 Escape

news/2025/10/24 21:15:51/文章来源:https://www.cnblogs.com/Water-M/p/19164238

房间情况记为 \(a_u\)

首先,判定能否逃走,可以在 \(t\) 点下面挂一个编号为 \(n+1\) 的点,权值为 \(+\infty\)。判定就转化为,能否在题设限制中,最终的体力达到 \(+\infty\)

然后考虑这个英雄会怎么走。
他可能会以一种弯弯扭扭,徘徊多次的姿态在树上游荡。具体地,他可能在第一次经过点 \(u\) 的时候,不足以打败 \(u\) 点的怪兽,导致他不能喝其子树中的魔泉;但是他可能会返回,在另一个分支中喝魔泉从而能有足够的体力打 \(a_u\)

一般人都会想 DP 对吧。设 \(f_{u}(x)\) 为,只考虑 \(u\) 子树中的情况,以 \(x\) 的体力进入 \(u\) 子树,出来的时候体力增加的最大值。

转移的时候,顺序是重要的。他甚至可以反复横跳。
所以没有一个确定的顺序来更新状态。

这里用若干个二元组的集合来刻画 \(f_u\)。二元组 \((a, b)\) 表示,\(x\ge a\) 的时候比 \(x < a\) 的时候,能多收 \(b\) 的体力。这样的二元组是不多的(可以从下面的更新过程中看到)。

\(f_u(x)\) 就是重复以下过程,直到集合为空。

  • 取出集合中最小的二元组 \((a, b)\) 并删除;
  • \(x \ge a\),则加上 \(b\) 的贡献,并令 \(x \gets x+b\)

显然 \(f_u(x)\) 单调不降。

容易看出,每次只需要暴力合并 \(u\) 的儿子 \(v\) 们的 \(f_v\),再考虑怎么加进 \(u\) 点的贡献就可以。
显然 \(a_u > 0\) 的情况,直接往 \(u\) 的集合里丢一个 \((0, a_u)\) 就行。下面重点讨论 \(a_u <0\) 的情况。

如果直接往集合里面加入一个 \((0, a_u)\) 讲道理是可以的。但是有两个限制没有考虑:

  • 进入 \(u\) 这个子树的最小初始体力为 \(-a_u\),也即 \(f_u(x)\) 的定义域是 \(x\ge -a_u\)
  • 那如果把 \(f_u(-a_u)\) 带进去有可能会得到一个负的结果,那还不如不进入这个子树。换句话说,\(f_u(x)\) 只有在 \(x\) 大于等于一个最小值 \(least\) 的时候才非负。

首先解决第二个限制。我们可以想一件事:
怎么求出在没有加进 \((0, a_u)\) 的集合中,最小的值 \(least\) 使得 \(f_u(least)\ge -a_u\)。这样才能使得 DP 有抉择的空间。

实际上不难。初始设定 \(least=0,extra =0,now=0\) 表示,\(f_u(least)\) 能得到的最多额外收益 \(extra\),以及实时更新的体力值 \(now\) 维护我们对 \(least\) 的调整。

重复以下过程直到 \(extra \ge -a_u\) 或集合为空:

  • 取集合中最小元素 \((x, y)\),并删除。
  • \(now\) 小于 \(x\),这时候初始值 \(least\) 并不足以让我们达到 \(-a_u\) 的额外收益。则让 \(least\) 加上 \(now\),并让 \(now \gets x\)。(这里 \(now\) 表示当前体力)
  • 额外收益 \(extra \gets extra + y\),现在的体力值 \(now \gets now + y\)

现在求出了 \(least\)\(extra\)。那这个 \(least\) 就表示,最小进入 \(u\) 子树的体力,使得在里面转一圈能回本。

进入 \(u\) 要花掉 \(u\) 的代价。所以实际上最小是要有 \(least - a_u\) 的进入体力。只需要在经历上面的过程之后,加入 \((least - a_u, extra + a_u)\) 就可以。

但这里有一个问题。可能 \(u\) 的集合中原来有一些第一关键字小于 \(least - a_u\) 的二元组。这也简单,删去这些二元组,把 \(extra\) 加上他们的第二关键字就可以。

用 priority_queue 表示集合,启发式合并做到 \(O(n\log^2n)\)。暴力删点不会影响复杂度,因为每个点最多被删一次。

#include <bits/stdc++.h>
using namespace std;//#define filename "xxx" 
#define FileOperations() freopen(filename".in", "r", stdin), freopen(filename".out", "w", stdout)
#define multi_cases 1#define inf 0x3f3f3f3f
#define Linf 0x3f3f3f3f3f3f3f3f
#define pii pair<int, int> 
#define ull unsigned long long
#define all(v) v.begin(), v.end()
#define upw(i, a, b) for(int i = (a); i <= (b); ++i)
#define dnw(i, a, b) for(int i = (a); i >= (b); --i)template<class T> bool vmax(T &a, T b) { return b > a ? a = b, true : false; }
template<class T> bool vmin(T &a, T b) { return b < a ? a = b, true : false; }
template<class T> void clear(T &x) { T().swap(x); }const int N = 2e5+5;#define int long longint n, t, a[N];
vector<int> G[N];priority_queue<pii, vector<pii>, greater<pii> > s[N];void DFS(int u, int fa) {for(auto v : G[u]) if(v != fa) {DFS(v, u);if(s[u].size() < s[v].size()) swap(s[u], s[v]);while(!s[v].empty()) s[u].push(s[v].top()), s[v].pop();}if(a[u] > 0) {s[u].push(pii(0, a[u]));}else if(a[u] < 0) {int least = 0, ex = 0, now = 0;while(ex < -a[u] && !s[u].empty()) {auto [x, y] = s[u].top();s[u].pop();if(now < x) least += x - now, now = x;ex += y, now += y;}while(!s[u].empty()) {auto [x, y] = s[u].top();if(x > least - a[u]) break;s[u].pop();ex += y;}if(ex >= -a[u]) s[u].push(pii(least - a[u], ex + a[u]));}
}void WaterM() {cin >> n >> t;upw(i, 1, n) cin >> a[i];upw(i, 1, n-1) {int u, v;cin >> u >> v;G[u].push_back(v), G[v].push_back(u);}a[++n] = 1000000000000000ll;G[n].push_back(t), G[t].push_back(n);DFS(1, 0);int res = 0;while(!s[1].empty()) {auto [x, y] = s[1].top();	s[1].pop();if(res >= x) res += y;}puts(res >= 1000000000000000ll ? "escaped" : "trapped");upw(i, 1, n) clear(G[i]), clear(s[i]);
}signed main() {
#ifdef filenameFileOperations();
#endifsigned _ = 1;
#ifdef multi_casesscanf("%d", &_);
#endifwhile(_--) WaterM();return 0;
}

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

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

相关文章

你可以把它喂给AI让AI猜猜我在干什么

// code by 樓影沫瞬_Hz17 #include <bits/stdc++.h> using namespace std;#define getc() getchar_unlocked() #define putc(a) putchar_unlocked(a) #define en_ putc(\n) #define e_ putc( )// #define int l…

nginx反向代理和负载均衡 - 实践

nginx反向代理和负载均衡 - 实践2025-10-24 21:10 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !import…

ABP - 审计日志 [AuditedAttribute、IAuditingManager、EntityAuditingHelper]

审计日志核心辅助类:AuditedAttribute:标记类/方法记录审计日志。 IAuditingManager:手动管理审计日志。 EntityAuditingHelper:实体审计辅助(自动填充创建/修改时间)。审计日志(Auditing)核心类示例与讲解 AB…

【深入浅出Nodejs】异步非阻塞IO

概览:本文介绍了阻塞I/O、非阻塞I/O、多路复用I/O和异步I/O 四种模型,在实际的操作系统和计算机中I/O本质总是阻塞的,通过返回fd状态和轮询的方式来使I/O在应用层不阻塞,然后通过多路复用的方式更高效实现这种不阻…

【Java-JMM】Happens-before原则

一、什么是 Happens-before 原则 Happens-before 原则是 Java 内存模型(JMM)的核心概念,用于定义多线程环境下操作之间的内存可见性关系。 核心理解:如果操作 A happens-before 操作 B,那么 A 的执行结果对 B 可见…

P6072 『MdOI R1』Path

给定一颗无根树 \(|T|\)。 求两条点不相交的路径,使得两条路径上边权的异或和加起来最大。 \[|T| \le 3\times 10^4 \] 这是一个经典 trick: 对于求两条点不相交路径,我们可以枚举点 \(x\),使得其中一条在 \(x\) 的…

P1601题解

题意 就是A+B,相信大家都能理解,对于Python来说很简单,对C++崽就不友好了 解析 下面提供一种解法(代码中的BitInt500这个类,别问我那个什么int128函数,不顶事): 1.创建数组 2.从字符串构造大型整数 3.大整数加法…

10-23 好题选讲总结

10-23 好题选讲总结 P13779 「o.OI R2」试机题 - 洛谷 注意特殊的数据范围。 \(K=2\) 就是黑白染色,然后检查黑白点数是否相等,\(K=3\) 可以 \(O(n^2)\) DP 设 \(f_{i,j,0/1}\) 表示子树内选了 \(j\) 个与 \(i\) 颜色…

关于驻马店市 2025 中小学信息学竞赛的记录(入门级)(未完)

全网好像都没有关于这个神秘竞赛的内容。 包括它的神秘举办方:驻马店市计算机学会。ZCF? 因此我决定写一篇记录,同时公布关于这个比赛的 几乎 所有信息。————题记By CasKPART 1. 赛前通知 本人是驻马店第*初级中…

关于Markdown的使用

因为在使用Markdown来编写博客,这里将会给出一些Markdown的笔记来方便后续使用。 标题采用#来表示几级标题,例如#为一级,##为二级。 这是一个一级标题 这是一个二级标题 字体采用*或者_来表示,一个表示斜体,两个表…

自定义Spring Cloud LoadBalancer实践

Spring Cloud负载均衡概述 在不同的Spring Cloud版本中,采用了不同的负载均衡组件。 具体来说,在Spring Cloud 2020.0版本之前,默认负载均衡器为Netflix推出的Ribbon,自Spring Cloud 2020.0版本起,Ribbon已经被标…

游记——驻马店市2025中小学信息学竞赛(未完)

全网好像都没有关于这个神秘竞赛的内容。 包括它的神秘举办方:驻马店市计算机学会。ZCF? 因此我决定写一篇游记,同时公布关于这个比赛的 几乎 所有信息。————题记By CasKPART 1. 赛前通知 以下是比赛前老师发给…

SAP折旧模拟超过1000条资产dump问题及解决

通过如下Tcode做资产折旧模拟时,发现如果超出100条资产系统会dump. S_ALR_87012936 - 折旧模拟 AR18N - 折旧模拟(新)解决办法: note:3396352 - Performance issues in Asset reporting or archiving, 可以配置单…

ABP - SqlSugar [SqlSugarModule、ISqlSugarClient、SqlSugarRepository]

SqlSugar ORM 集成 核心辅助类:SqlSugarModule:SqlSugar集成模块(需手动引入社区包)。 ISqlSugarClient:SqlSugar核心客户端。 SqlSugarRepository<T>:基于SqlSugar的仓储实现。你关注到了ABP与SqlSugar O…

Odoo18.0 对接 京东快递

京东快递 本章我们来看一下如何使用我们欧姆网络科技的京东快递插件来完成Odoo与京东快递的对接。 前期准备 首先我们要先在京东快递的开放平台注册一个商家[自研商家],并完成认证签约。入驻之后我们需要拿到如下参数…

Matplotlib常见画图工具

View PostMatplotlib常见画图工具一、Matplotlib核心基础 在开始绘图前,需掌握以下基础框架,几乎所有图表都基于此扩展:点击查看代码 # 1. 导入库 import matplotlib.pyplot as plt import numpy as np # 用于生成…

[python] 代码性能分析工具line_profiler使用指北

代码分析能够评估各部分代码的时间消耗,即进行时间复杂度分析。通过这一过程,我们可以识别影响整体运行效率的关键部分,从而更高效地利用底层计算资源。此外,代码分析也可用于评估内存使用情况,即空间复杂度,以优…

react的diff算法

这个算法用来比较虚拟dom和真实dom,从而最小化真实dom的更新 本质上是对两颗Fiber树的对比 (在Vue中是对旧VDOM树与新VDOM树的对比) 在不剪枝的情况下,时间复杂度接近O(n^3)基于最长公共子序列 (LCS) 的朴素计算为…

LLM学习记录DAY11

📘今日学习总结 tokenization分词算法 BPE分词(Byte-Pair Encoding)BPE 算法从一组基本符号(例如字母和边界字符)开始,迭代地寻找语料库中的两个相邻词元,并将它们替换为新的词元,这一过程被称为合并。 合并的…

ABP - 当前用户 [ICurrentUser、CurrentUser]

当前用户(Current User) 核心辅助类:ICurrentUser:获取当前登录用户信息(ID、用户名、角色等)。 CurrentUser:静态快捷访问(需在请求上下文内)。在ABP框架中,ICurrentUser和CurrentUser用于获取当前登录用户…