[题目记录]AGC005E Sugigma: The Showdown

news/2025/1/10 16:35:22/文章来源:https://www.cnblogs.com/youlv/p/18664201

AGC005E Sugigma: The Showdown

题意

给出两棵树 , 点的编号相同 , 连边方式不同 .

初始 A 在树 \(a\) 上的点 \(x\) , B 在树 \(b\) 上的点 \(y\) , 两人轮流走 , 每人每轮可以向所在树上的一个相邻点走一步 , 也可以不走 . 当两个人所在的点编号相同时游戏结束 .

A 要最大化轮数 , B 要最小化轮数 , 问游戏轮数 . 如果可以进行无限轮 , 输出 \(-1\) .

\(n\le 2\times 10^5\) .


题解

首先发现可以把这个问题理解成 B 追逐 A . 然后发现 B 的决策可以说是相当 "被动" 的 . 首先 B 任何一轮都不会选择不动 , 因为如果 B 不动 , A 完全可以不动 , 相当于白白多了一轮 . 同理 , B 也不可能向着远离 A 的方向移动 , 否则 A 也可以不动让 B 至少亏一轮 .

因此 B 的决策是固定的 : 每次向 A 当前所在位置移动一格 .

此时只需研究 A 的决策即可 .


先研究一下题目中说的无限轮的情况 , 研究样例 4 , 发现这里是因为有一条 \(a\) 边连接了 \(b\) 树上的一条路径 , A 只需在 B 走到这条路径靠近自己的一半时换到另一边即可 , 而为了实现能 "遛" B , 这条路径的长度需要 \(\ge 3\) .

因此 " 所有 \(a\) 边对应的 \(b\) 树上路径长度 \(<3\) " 是轮数有限的 充分不必要条件 . 先考虑这个子问题 .

这提示我们从每一条 \(a\) 边跨越的 \(b\) 树上的路径来思考 . 考虑以 \(y\) 为根 , 把 \(b\) 视作有根树 , 把 \(a\) 视作 \(b\) 树上的一些连接边 .

这样变化后 , 因为每条 \(a\) 边所能跨越的长度 \(<3\) , 最多只能从根的一个儿子移动到另一个儿子 , 子树中的其他点都不能联通 , 而根的任何一个儿子都会在下一步被追上 . 因此 **A 无法在 B 当前所在节点的不同子树间移动 ** .

( A 此时只能向它自己的子树移动 )

这也侧面证明了上面的结论是正确的 , 因为 B 总是在缩小 A 可以移动的子树 , 直到 A 移动到一个叶子节点 , 游戏结束 .

而 A 要最大化轮数 , 只能移动到一个深度尽可能大的叶子 . 然而进入哪个叶子不完全由 A 决定 , 比如如下情况 :

虽然左侧的链可以让轮数更多 , 但是 A 走到左儿子需要 \(3\) 步 , 然而仅 \(1\) 步之后左子树就会被向下走了一步的 B 封锁 . 究其原因 , A 走到右儿子需要两步 , 而 B 也需要两步 , 恰好在这一步结束 .

因此对于每个点设 \(d_u\) 为在 \(a\) 树 ( 以 \(x\) 为根 ) 上的深度 , \(d'_u\) 为在 \(b\) 树上的深度 , 只有在 $d_u<d'_u $ 时 , 这个点才能在不在当前点被追上的情况下到达 , 而要到达 \(u\) 需要保证从 \(y\)\(u\) 的路径都满足 \(d_x<d'_x\) .

通过这种方法 , 可以获得所有能够到达的点 , 取其中深度最大的点计算答案 .


然后考虑存在 \(\ge 3\) 的边 . A 只要到达这种边的一个端点 , 就可以达到无限轮 , 到达这种边的端点相当于到达的终点 , 后面无需考虑 .

因此仍然只考虑 \(<3\) 的边 , 用刚才的方法把所有能到达的点找出来 , 如果能到达 $\ge 3 $ 的边的端点就是无限轮 , 否则取深度最大的点计算答案 .

点击查看代码
#include<bits/stdc++.h>
#define file(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define ll long long
#define INF 0x3f3f3f3f
#define INF64 1e18
using namespace std;constexpr int N=2e5+5;vector<int> e[N],g[N];
vector<pair<int,int> > ep;int n,x,y;int d[N],dep[N],dfn[N],rnk[N],tot,pos[N],fd[N*2][22],od,lg[N*2];void dfs1(int u,int fa){dfn[u]=++tot;rnk[tot]=u;fd[++od][0]=dfn[u];pos[u]=od;for(auto v:g[u]){if(v==fa) continue;dep[v]=dep[u]+1;dfs1(v,u);fd[++od][0]=dfn[u];}
}
void init(){for(int j=1;(1<<j)<=od;j++)for(int i=1;i+(1<<j)-1<=od;i++)fd[i][j]=min(fd[i][j-1],fd[i+(1<<(j-1))][j-1]);lg[1]=0;for(int i=2;i<=od;i++) lg[i]=lg[i/2]+1;
}
int LCA(int x,int y){x=pos[x],y=pos[y];if(x>y) swap(x,y);int t=lg[y-x+1];return rnk[min(fd[x][t],fd[y-(1<<t)+1][t])];
}int dist(int x,int y){return dep[x]+dep[y]-2*dep[LCA(x,y)];
}bitset<N> vis;int res,ok;void dfs2(int u,int fa){if(d[u]>=dep[u]) return;if(vis[u]) ok=1;else res=max(res,dep[u]);for(auto v:e[u]){if(v==fa) continue;d[v]=d[u]+1;dfs2(v,u);}
}int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n>>x>>y;for(int i=1;i<n;i++){int u,v;cin>>u>>v;ep.push_back({u,v});}for(int i=1;i<n;i++){int u,v;cin>>u>>v;g[u].push_back(v);g[v].push_back(u);}dfs1(y,y);init();for(auto [u,v]:ep){if(dist(u,v)>2) vis[u]=vis[v]=1;e[u].push_back(v);e[v].push_back(u);}dfs2(x,x);if(ok) cout<<-1;else cout<<2*(res);
}

总结

非常有趣的思维题 , 层层推进 , 靠自己生成思路也不算很难 .

首先可以通过研究博弈过程得到其中一方的固定决策 , 而把问题简化成单方面的最优化 .

然后这道题给出了很好的切入点 : 无限轮数 . 而且样例 4 , 5 覆盖了带 \(\ge 3\) 的边的两种情况 , 非常自然地提示我们把边分类考虑 , 最后变成了研究每个点能不能到达的问题 , 简单解决这个子问题就完事了 .

学会找切入点很重要 , 好的切入点快速抓住主要矛盾 , 并且提供很多信息或者方向 .

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

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

相关文章

代码随想论算法训练营第3天 | 链表理论基础,203.移除链表元素,707.设计链表,206.反转链表

一、刷题部分 1.1 链表理论基础原文链接:代码随想录 题目链接:🈚️链表是由一个个节点串联而成的,节点包含数据域和指针域,数据域用来存放数据,而指针域实现了节点之间的串联。 链表中有单链表、双链表、循环链表:链表的物理空间是不连续的,通过指针存储下一节点的物理…

ABAP配置:OY01 定义国家/地区

配置:OY01 定义国家/地区 事务代码:OY01 配置路径 SPRO-ABAP平台-常规设置-设置国家-定义国家/地区 配置路径截图配置描述 国家是SAP里面一个非常重要的概念,SAP国家概念涉及公司代码、工厂、主数据、跨国银行交易,系统默认自带ISO相关的国家编码,在S/4中,一些配置转移到…

关于GTM,这些评价指标你都知道吗?

目标跟踪指标是企业实现持续增长和盈利的重要工具。通过定期监控和分析这些指标,企业可以及时发现潜在问题并采取相应的改进措施,以保持其竞争力并实现业务目标。因此,企业应该重视这些指标的应用,并不断优化其监控和分析流程,以确保其业务运营的顺利进行。Goal Tracking …

ODX诊断数据库转换工具 - DDC

INTEWORK-DDC (Diagnostic Database Convertor) 是将诊断调查问卷转换为标准ODX(2.2.0)数据库的工具。ODX是格式标准化的诊断数据库文件,我们在诊断不同的车或者不同的ECU时,只需要加载适配这个车型或ECU的ODX文件即可,而无需对诊断仪做任何改变。ODX统一了诊断文件的格式,…

异地多活架构进阶:如何解决写后立即读场景问题?【转】

在《醍醐灌顶!异地多活架构设计看这篇就够了》一文中,基于容灾需要,讨论了数据写入的架构模型。数据读取方面,重点在于解决读取请求的负载分担、路由选择的问题,对于容灾架构的选择影响不大。不过,其中的“写后立即读”场景,是个一致性范畴的问题,即写入的数据和写入后…

JAVA之面向对象

1、设计对象并使用类和对象 类(设计图):是对象共同特征的描述; 对象:是真实存在的具体实例; 在java中,必须先设计类,才能获得对象。 如何得到类的对象:类名 对象名 = new 类名(); 如何使用对象: 访问属性:对象名.成员变量 访问行为:对象名.方法…

免费手动打Windows Server补丁

免费手动打Windows Server 2008 R2补丁https://catalog.update.microsoft.com/search.aspx?q=kb4474419然后到windows上双击运行即可本文来自博客园,作者:六月OvO,转载请注明原文链接:https://www.cnblogs.com/chenlifan/p/18664077

pwn1_sctf_2016 1

打开ida反汇编看一下,是c++,无所谓,复制问一下ai先让我们输入s的数据,读取长度限制在32字节。然后replace函数会将s里面的 I 替换成 you 。最后输出s。 分析一下,s距离ebp为0x3C(60字节),且我们最多只能输入32字节的,但经过replace函数,一个字节的‘I’会被替换成三个…

UDS-ECU程序刷写

UDS(unified diagnostic services)统一诊断服务主要是针对汽车上对ECU进行诊断服务规范,下图是UDS在OSI分层中的具体规范,基于UDS的刷写应用逻辑体现在应用层的ISO14229规范。一、功能介绍 UDS(unified diagnostic services)统一诊断服务主要是针对汽车上对ECU进行诊断服…

主体分割技术,提升图像信息提取能力

在智能设备普及和AI技术进步的推动下,用户对线上互动的质量、个性化以及沉浸式体验的追求日益增强。例如,对于热衷于图片编辑或视频制作的用户来说,他们需要一种快速而简便的方法来将特定主体从背景中分离出来。 HarmonyOS SDK 基础视觉服务(Core Vision Kit)提供主体分割…

qt 实现窗口置顶,qtdesigner创建的widget窗口集成程序里的用法

参考 https://blog.csdn.net/Larry_Yanan/article/details/123518788 .ui文件如下新建的ui文件,编译一下就会生成对应的 ui_xxx.h 文件,文件内就有对应的 namespace Ui 声明的变量,这个变量要在mainwindow.h中声明,然后在mainwindow.cpp中new出来,具体使用如下 mainwindow…

如何在市场推广活动中实现精准的任务分配?5个项目管理技巧

一、引言 随着市场竞争的加剧和消费者需求的多样化,企业对市场推广活动的要求越来越高。市场推广活动不仅需要创意和精准的目标定位,还需要高效的执行和完善的管理。在这种背景下,如何通过有效的活动管理来提升推广活动的执行力,已成为市场团队面临的一个巨大挑战。 市场推…