Loading

CF记录

CF2019(div2,vp)

比赛时网站炸了两次,有一次甚至连那个 Oops 的页面都没看到。/fn

D. Speedbreaker

做法比较多的一题。
首先有一个带 log 但是比较简单的做法。求出 \(a\) 的后缀 min \(s_i\) 和前缀 min \(p_i\),当出发点为 \(x\) 时,设

\[b_i=\begin{cases}a_i=p_i, &i<x\\ a_i=\min(p_i,s_i),&i=x\\ a_i=s_i,&i>x \end{cases}\]

\(x\) 可行当且仅当对于每一个 \(j\)\(\leq j\)\(b_i\) 数量不超过 \(j\)。事实上这是一个经典结论。然后用线段树维护就行了。

另一个与这个做法类似的线性做法是,将对于每个点判定转化为判定有哪些点,
即可行的 \(x\) 满足\(a_i\) 改为 \(1\),包含所有 \(a_i\leq j\) 的点的最小子区间 \([l_j,r_j]\) 的长度不超过 \(j\)
这样对于每个 \(j\),可以得到可行的 \(x\) 一定在 \([r_j-j+1,l_j+j-1]\) 中,取一下交集就行了。

还有一种双指针做法利用到可行的 \(x\) 一定是一个区间的性质,与另一个观察。
具体地,对于一对 \(l,r\),若 \(x\notin[l-a_l+1,l+a_l-1]⋂[r-a_r+1,r+a_r-1]\)\(a_l<r-l+1⋀a_r<r-l+1\),则 \(x\) 是不可行的。
于是可以双指针。初始设 \(l=1,r=n\)。如果 \(a_l\geq r-l+1\),则对于更小的 \(r\) 都有相同的结论,这个 \(l\) 没有用了,\(l\) 增加 \(1\)\(r\) 同理。

posted @ 2024-10-10 23:16  AsiraeM  阅读(18)  评论(0)    收藏  举报