NOI D1T1 合集

为了防止菜鸡 Scintilla 在 NOI2021 网络同步赛中保龄,他找了一些 NOI D1T1 来做。

NOI2020 D1T1 美食家

Description

给定一张 n 个点、m 条边的有向图,点 u 有点权 cu、边 i 有边权 wi,有重边无自环。你需要在第 0 秒从 1 号点开始走,走一条边的秒数为其权值,经过一个点 u 可以获得 cu 的收益。特别地,有 k 个特殊情况,每组特殊情况形如 t,x,y,表示在第 t 秒走到点 x 可以额外获得 y 的收益。你需要在恰好第 t 秒回到 1 号点,求最大收益。

n50,nm501,k200,wi5,ci52501

1ui,vi,xin,tiT109,yi109

Solution

看到 n 很小、T 很大,第一时间想到矩乘。

一个显然的想法是设 fi,j 表示第 i 秒到达 u 号点的最大收益、gi,u 表示在第 i 秒到 u 号结点的额外收益,那么转移就是

fi,u=max(v,u,w)Efiw,v+cu+gi,u

但是这个东西普通的矩乘貌似不能做,因为转移是 max 形式的。首先考虑这样的 max 转移是否具有结合律。

定义矩阵的 操作(即上面的转移形式)为

(AB)i,j=maxk{Ai,k+Bk,j}

A,B,C 为三个矩阵,有

((AB)C)i,j=maxp{maxq{Ai,q,Bq,p}+Cp,j}=maxq{Ai,q+maxp{Bq,p,Cp,j}}=(A(BC))i,j

所以这里的结合律依然存在,快速幂依然有用。但是还有一个问题我们没有处理——特殊情况。因为 k200,我们可以把特殊情况按照 t 排序,乘到一个 t 就停下来将对应的值加上额外收益,再继续乘即可,但这样的时间复杂度 O((5n)3klogT),有点爆炸。

设转移矩阵为 T,DP 矩阵为 F。发现我们每一次都是先乘好 T 的幂次再把 F 和它乘,但事实上我们可以预处理出 T2i 次幂,每次都拿 FT2i 次幂乘,因为 FT2i 的一次乘法是 O((5n)2) 的,所以可以将复杂度降至 O((5n)3logT+(5n)2klogT),可以接受。


NOI2019 D1T1 回家路线

Description

n 个点,你在第 0 时刻位于第一个点,你需要走到第 n 个点。有 m 班列车,第 i 班列车在时刻 pi 从点 xi 出发,在时刻 qi 到达点 yi,只能在时刻 pi 上车、时刻 qi 下车。给定函数 f(x)=Ax2+Bx+C,设 s1,,sk 为一个合法的回家列车序列,定义这个序列的代价为

qsk+f(ps1)+i=2kf(psiqsi1)

求所有合法回家列车序列的最小代价。

原题数据范围:n105,m2×105,A10,B,C106,0pi<qi103

加强版数据范围:n105,m106,A10,B,C107,0pi<qi4×104

Solution

预处理出从每个点出发和到每个点的列车,把所有列车按照 q 排序,设 fi 为乘坐第 i 号列车时的最小代价,那么转移显然,这样暴力做就能拿到 70 分。

一个想法是斜率优化,但是发现能够转移的点并不连续,所以不能直接莽斜率优化。我们可以对 p 的值域分块,但这样还是过不了加强版。不过直接把所有 pi 的询问离线即可,换句话说就是把一条边拆成加数和查询两个操作,可以直接按照时间排序。时间复杂度 O(mlogm)

注意斜率优化时判横坐标相等!!!


NOI2018 D1T1 归程

Description

给定一张 n 个点和 m 条边的图,每条边有一个长度和一个权值。有 q 组询问,每组询问给定两个数 up。对于一条 u1 的路径,设 v 为路径上从 u 开始第一条权值不大于 p 的边离 u 较远的那个结点(若不存在这样的边则令 v1),定义这条路径的代价为 v1 路径上边的长度和,询问 u1 所有路径的最小代价。

强制在线,n2×105,m4×105,q4×105

Solution

  • 关于 SPFA
  • 它死了

首先我们需要知道一个叫做 Kruskal 重构树的东西。

Kruskal 重构树是一棵部分点有点权的树。它的构造方法如下:在 Kruskal 算法进行的过程中,对于加入的第 i 条边,新建一个编号为 n+i 的结点,它的两条边连向合并的两个集合的根,并将它的点权设为当前这条边的长度,然后将新节点设为根。不难发现最后形成了一个二叉树的结构,我们就把这棵树称为 Kruskal 重构树。

那么 Kruskal 重构树有什么性质呢?不难发现,最小生成树上两个结点简单路径上的最大权值就是他们 LCA 的点权。

回到原题。不难发现可以找到至少一条答案路径在原图的权值最大生成树上,结合上面的性质,发现所有符合要求的点就是以 u 的所有祖先中权值深度最小的权值大于 p 的结点的子树。于是我们可以预处理出子树内部的点到 1 号点的 min 值、找到那个点可以树上倍增。

时间复杂度 O(nlogn)(默认 n,m,q 同阶)。


NOI2017 D1T1 整数

Description

有一个整数 x,刚开始为 0,你需要支持两种操作:

  • 给定整数 a 和非负整数 b,令 xx+a2b
  • 给定整数 k,询问 x 二进制下代表 2k 的一位的值。

n106,|a|109,b,k30n,保证任何时刻 x 非负。

Solution

一个想法是用 bitset 之类的维护 x 这个数,但是因为 a 可能为负,这个算法的时间复杂度会退化到 O(k2log|a|ω)

发现修改是区间赋值,又看到 30n 这个奇妙的东西,可以压位上线段树,时间复杂度 O(nlognlogai),貌似可以艹过去。

posted @   Scintilla06  阅读(209)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示