AtCoder Beginner Contest 267

https://atcoder.jp/contests/abc267

全部的 AC 代码:

https://atcoder.jp/contests/abc267/submissions/me?f.Task=&f.LanguageName=&f.Status=AC&f.User=HinanawiTenshi

E

题目要求最小化花费,而花费是所有花费的最大值,故考虑二分,记现在二分的值 midlim

因为每次代价都是与删点所连点的边权和,所以尽量去找当前花费 lim 的,找不到当然就继续去二分更大的值。

因此,我们可以执行一个 bfs,每次找花费 lim 的点进行扩展,并在扩展当前点的同时对其邻点更新花费(也就是减去当前点权),当临点更新后花费 lim 时入队。

F

由于需要求 u 点跳 k 步能够到达的树上的点,故尽可能找到 u 能够跳到的最远点,因为如果 u 跳到最远点都不足 k 步,那么必然无解

什么点可能成为距 u 的最远点呢?直观的想法是直径的两个端点 x,y

证明:

不妨设 dis(u,x)dis(u,y)

假设能够找到点 v 使得 dis(u,v)>dis(u,x),那么找到 u 到达路径 x,y 上的点 u

我们有 dis(u,v)>dis(u,x),故 dis(u,v)+dis(u,y)=dis(v,y)>dis(u,x)+dis(u,y)=dis(x,y),与 x,y 为直径矛盾。

证毕。

下面的做法很简单:

就分别以 x,y 为根节点,求出 uk 级祖先即可。

G

为了方便转移,对所给序列 w 进行升序排序

容易想到状态表示 f[i,j] 为前 i 个元素共有 j 个位置 pos 满足 wpos<wpos+1。(记为顺序位置

考虑 f[i,j] 如何转移到后面的状态。

对于第 i+1 个元素 wi+1,可以发现当插入 wi+1 时(也就是将 wi+1 挑选 [1,i+1] 一个位置放入),要么会使原来的顺序位置个数不变,要么比原来多 1

  • 对于不变的情况,有多少种方案呢?

    • 首先,插入位置 1 肯定不变,有一种。
    • 插入到与 wi+1 等值的元素(记这样的元素有 cnt 个)后面,有 cnt 种。
    • 插入到已经产生的顺序位置 pos 的后面(也就是插入 pos,pos+1 之间),有 j 种。

    因此,f[i,j]f[i+1,j] 的贡献为:f[i+1,j]+=f[i,j]×(1+cnt+j)

  • 比原来多 1 的情况就是不变情况的补,即有 i+1(1+cnt+j)=ijcnt 种,

    因此,f[i,j]f[i+1,j] 的贡献为:f[i+1,j+1]+=f[i,j]×(ijcnt)

EX

注意到值域很小,所以直接将答案拆奇偶然后进行 NTT 分治来合并背包即可。

记当前区间 u 取奇数个物品的背包为 uo,偶数个的为 ue,左右子区间分别记为 ls,rs

分治过程即:

uo=merge(lse,rso)+merge(lso,rse)ue=merge(lse,rse)+merge(lso,rso)

merge 用 NTT 卷积即可。

posted @   HinanawiTenshi  阅读(110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示