2023.10.31 模拟赛总结
总结
时间安排
\qquad
没啥可说的,罚坐全场,中间有一段狂交 rand 刷分,开启 IOI 赛制。
考试总结
\qquad
虽然本场题非常恶心,区分度不高,但是还是有些分没拿到。像
T3
\text{T3}
T3 的
O
(
q
n
)
O(qn)
O(qn) 的
dp
\text{dp}
dp 或贪心,
T1
\text{T1}
T1 的爆搜(没写是因为感觉细节太多,不是很会处理)。考场上看到难题要想尽办法磕部分分啊……
题解
T1
\qquad 看到数据范围,果断状压 dp \text{dp} dp。容易想到的一个 dp \text{dp} dp 转移方法是:设 dp m a s k \text{dp}_{mask} dpmask 表示由 mask \text{mask} mask 状态到最终状态所需的最短时间,然后每次进行一个新操作去转移。但是,不难发现,这么转移有两个弊端:其一,它有后效性,因为你不知道当前状态 mask \text{mask} mask 在新加一个操作后的新状态 mask’ \text{mask'} mask’ 跟 mask \text{mask} mask 比谁大,这意味着转移时不能固定一个枚举顺序。但是这个问题很好解决,每当状态有后效性的时候,考虑加维度即可。其二,我们往后加操作时,前面所有操作都需要往后延伸一秒,非常难处理。而这个问题的解决方案很妙。
\qquad 我们考虑两个操作序列:1,从第 1 1 1 秒开始,以后三秒内分别操作第 1 , 2 , 3 1,2,3 1,2,3 号节点;2,第 1 1 1 秒不进行任何操作,从第 2 2 2 秒开始,以后三秒内分别操作第 1 , 2 , 3 1,2,3 1,2,3 号节点。不难发现,这两种操作序列的最终状态是相同的。这意味着,我们可以把向后添加操作转变为向前添加操作,这样我们就只需关心新添加操作在若干秒后的状态了。
\qquad 综上,我们最终的 dp \text{dp} dp 为:设 dp i , m a s k \text{dp}_{i,mask} dpi,mask 表示第 i i i 秒后能否到达状态 mask \text{mask} mask,同时,我们预处理一个 w i , j \text{w}_{i,j} wi,j 表示对点 i \text{i} i 进行操作, j \text{j} j 秒后树的状态,那么 dp \text{dp} dp 转移式就很好写了,具体见 Code \text{Code} Code。
\qquad 核心 Code \text{Code} Code:
T2
\qquad 这题真的很难想……
\qquad 看到本题,第一直觉应该就是隐式建图。但是怎么建呢?考虑到本题给了每个人一个最终状态,学会、没学会或无所谓,这相当于是一个限制,所以我们就从限制入手。我们设 maxT i \text{maxT}_i maxTi 表示第 i \text{i} i 个人最早得在什么时候学会算法。形式化地说,如果设 t i \text{t}_i ti 表示第 i i i 个人学会毒瘤算法的时间,那么 maxT i ≤ t i \text{maxT}_i \leq \text{t}_i maxTi≤ti。显然,最终没学会的人(设其状态为 w i = − 1 \text{w}_i = -1 wi=−1)的 maxT i \text{maxT}_i maxTi 为 + ∞ +\infty +∞。我们想:如果有一个 w i ≠ − 1 \text{w}_i\ne -1 wi=−1 与 w j = − 1 \text{w}_j=-1 wj=−1 的人必须要在 [ L k , R k ] [\text{L}_k,\text{R}_k] [Lk,Rk] 内吃饭,那么人 j \text{j} j 可以给人 i \text{i} i 一个什么限制呢?如下图:
\qquad
我们想:若
maxT
i
\text{maxT}_i
maxTi 处于位置①,那么就意味着在他们吃饭前人
i
\text{i}
i 就学会了算法,这就意味着无论他们在哪一天吃饭,人
j
j
j 都将学会毒瘤算法,这显然是不合法的。但是,如果
maxT
i
\text{maxT}_i
maxTi 处于位置②,那么我们只要将他们吃饭的时间安排在
[
L
k
,
maxT
i
−
1
]
[\text{L}_k,\text{maxT}_i-1]
[Lk,maxTi−1],就可以同时保证两人维持合法状态。所以此时人
j
\text{j}
j 会限制人
i
\text{i}
i 的
maxT
≥
L
+
1
\text{maxT}\geq \text{L}+1
maxT≥L+1。那么,我们继续想:若一个人
i
\text{i}
i 要在
[
L
k
1
,
R
k
]
[\text{L}_{k1},\text{R}_k]
[Lk1,Rk] 和
[
L
k
2
,
R
k
]
[\text{L}_{k2},\text{R}_k]
[Lk2,Rk] 这两个时间段分别与两个
w
j
=
−
1
\text{w}_j=-1
wj=−1 的人吃饭,那么此时
maxT
i
\text{maxT}_i
maxTi 会受到什么限制呢?显然是
maxT
≥
max
(
L
k
1
+
1
,
L
k
2
+
1
)
\text{maxT}\geq \max(\text{L}_{k1}+1,\text{L}_{k2}+1)
maxT≥max(Lk1+1,Lk2+1),需要取
max
\max
max。
\qquad
通过上面的分析,我们知道
w
=
−
1
\text{w}=-1
w=−1 的人可以限制
w
≠
−
1
\text{w}\ne -1
w=−1 的人,那么
w
≠
−
1
\text{w}\ne -1
w=−1 的人之间能不能互相限制呢?答案是可以的。我们想,什么情况下这种限制才是有意义的呢?
\qquad
我们想:假设当前人
i,j
\text{i,j}
i,j 的
w
≠
−
1
\text{w}\ne -1
w=−1,
maxT
i
\text{maxT}_i
maxTi 在③或④位置,
maxT
j
\text{maxT}_j
maxTj 在①或②位置。我们分类讨论一下:1、若
maxT
i
\text{maxT}_i
maxTi 在③位置,那么如果我们把两人的吃饭时间安排在
[
maxT
i
,
R
k
]
[\text{maxT}_i,\text{R}_k]
[maxTi,Rk] 之间,便可以让人
i,j
\text{i,j}
i,j 同时满足条件。因为此时人
i
\text{i}
i 已经学会了,完全可以教给人
j
\text{j}
j,并不会给
maxT
j
\text{maxT}_j
maxTj 带来限制。但是如果
maxT
i
\text{maxT}_i
maxTi 在位置④,就意味着人
i
\text{i}
i 在此次饭局中不能学会,那么我们就可以把他们安排在
L
\text{L}
L 吃饭,然后限制
maxT
j
=
L
+
1
\text{maxT}_j=\text{L}+1
maxTj=L+1。所以这表明,只有当
maxT
i
>
R
+
1
\text{maxT}_i > \text{R}+1
maxTi>R+1 的时候才会给
maxT
j
\text{maxT}_j
maxTj 带来限制。2、若
maxT
j
\text{maxT}_j
maxTj 在位置②,就意味着之前已经有一个
i’
\text{i'}
i’ 限制了
maxT
j
\text{maxT}_j
maxTj,而且限制的要比
i
\text{i}
i 更晚,这就意味着
i
\text{i}
i 并不会给
j
\text{j}
j 带来限制。综上,只有当
maxT
j
≤
L
≤
R
<
maxT
i
\text{maxT}_j\leq \text{L}\leq \text{R}<\text{maxT}_i
maxTj≤L≤R<maxTi 的时候,转移才有意义。
\qquad 清楚了转移的原理,我们来想一下转移的实现。通过上面的分析,我们不难发现: maxT \text{maxT} maxT 的值总是由大的一个转到小的一个,而且对于单个 maxT i \text{maxT}_i maxTi 只会越转越大,最终在所有可能的转移中取 max \max max。这是不是类似于 Dijkstra \text{Dijkstra} Dijkstra 呢?我们每次从堆顶取出 maxT \text{maxT} maxT 最大的一个(保证已被限制到了最终状态),然后去更新其他的。这样,我们的转移就成功实现了。
\qquad 在这一转移结束后,我们想:如果 maxT 1 > 0 \text{maxT}_1>0 maxT1>0,是不是意味着一号节点被限制在 0 0 0 时刻之后才能学会?这与 1 1 1 节点开始就会的规定不符,所以我们可以直接判 Impossible \text{Impossible} Impossible。
\qquad
接下来,我们考虑,上面这个转移结束后,整道题就结束了吗?显然没有。上面这一转移中我们只说明了存在一种方案使得所有
w
=
−
1
w=-1
w=−1 的人满足条件,但是并没有顾及到
w
=
1
w=1
w=1 的人。怎么办呢?考虑到如果一个
w
=
1
w=1
w=1 的人要学会,那肯定是越早越好。我们效仿上面的过程,设
d
i
\text{d}_i
di 表示人
i
i
i 最早什么时候能学会。显然,初始时
d
1
=
0
\text{d}_1=0
d1=0,其余的为正无穷。我们思考,人
i
\text{i}
i 给人
j
\text{j}
j 转移时,有哪些限制条件呢?
\qquad
在上图中,我们可以清晰地发现,
d
j
\text{d}_j
dj 需要同时满足:大于等于
d
i
\text{d}_i
di,大于等于
L
k
\text{L}_k
Lk,大于等于
maxT
j
\text{maxT}_j
maxTj。同时,
d
j
\text{d}_j
dj 还需要小于等于
R
k
\text{R}_k
Rk。形式化地说,我们设
maxx
=
max
(
d
i
,
max
(
L
k
,
maxT
j
)
)
\text{maxx}=\max(\text{d}_i,\max(\text{L}_k,\text{maxT}_j))
maxx=max(di,max(Lk,maxTj)),当
maxx
≤
R
\text{maxx}\leq \text{R}
maxx≤R 且
maxx
<
d
j
\text{maxx}<\text{d}_j
maxx<dj 时,
d
j
=
maxx
\text{d}_j=\text{maxx}
dj=maxx。最后,如果有一个
w
=
1
\text{w}=1
w=1 的人
i
\text{i}
i,他的
d
i
=
+
∞
\text{d}_i=+\infty
di=+∞,那么我们就可以直接判
Impossible
\text{Impossible}
Impossible。
\qquad 这个转移结束后,所有 w = 1 , − 1 \text{w}=1,-1 w=1,−1 的人全都考虑到了,一定存在一个合法状态使得他们都满足条件。但是我们好像忽略了一种人: w = 0 \text{w}=0 w=0 的人!那么 w = 0 \text{w}=0 w=0 的人怎么处理呢?显然的是, w = 0 \text{w}=0 w=0 的人是不能用来判 Impossible \text{Impossible} Impossible 的,因为他最终状态是啥无所谓。但是他有一个传递限制的作用。例如一个 w = 1 \text{w}=1 w=1 和另一个 w = − 1 \text{w}=-1 w=−1 的人要同时和一个 w = 0 \text{w}=0 w=0 的人吃饭,那么这个 w = 0 \text{w}=0 w=0 的人就会把 − 1 -1 −1 带来的限制传给 w = 1 \text{w}=1 w=1 的人。这意味着我们并不需要对 w = 0 \text{w}=0 w=0 的人做任何特殊操作,正常转即可。
\qquad 核心 Code \text{Code} Code:
T3
\qquad 首先,我们先考虑本题的 Θ ( Qn ) \Theta(\text{Qn}) Θ(Qn) 做法怎么写?既然要在 Θ ( len ) \Theta(\text{len}) Θ(len) 的时间复杂度内完成区间查询,那就一定是一维 dp \text{dp} dp 或贪心去搞。但是考虑到贪心拓展性小,我们考虑设计 dp \text{dp} dp 状态。设 dp i , 0 / 1 \text{dp}_{i,0/1} dpi,0/1 表示:考虑到第 i i i 个位置, 0 0 0 表示全是 0 0 0, 1 1 1 表示末尾有一段连续一的最小操作步数。状态设计好之后,转移其实并不难,简单分讨一下即可。
\qquad 核心 Code \text{Code} Code:
\qquad 现在我们考虑优化。注意到每次的转移只与 i − 1 \text{i}-1 i−1 有关,而且当 s i \text{s}_i si 定了之后,每次转移在 0 / 1 0/1 0/1 之间加的系数是相同的,所以我们考虑用线段树维护一个类似矩阵的转移。建树和修改就变得非常简单,但是查询的时候有一点细节。我们不能直接查 [ l , r ] [\text{l},\text{r}] [l,r] 的矩阵,而是应该判断 l \text{l} l 的值,然后与 [ l + 1 , r ] [\text{l}+1,\text{r}] [l+1,r] 的矩阵结合后再输出。
\qquad Code \text{Code} Code:
__EOF__

本文链接:https://www.cnblogs.com/best-brain/p/18006556.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)