11.5比赛题解

模因病毒

原题链接

大乌龙:理解错题辣!

我理解的是两只猴子手拉手,结果是一只猴子用手拉着另一只猴子,当连着的两只猴子都松手时猴子才会掉下去。

这道题思路比较巧妙也比较常见:正难则反。

考虑正推,好像要带撤销并查集(觉得挺难,非要写应该也可以),面对这种删边问题,一般都是通过倒推的方法变为加边问题,往往会好做。

所以考虑倒推,问题转换为:通过不断加边,则每个点的掉落时间为它第一次与 1 号节点联通的时间,可用并查集维护。

但是,一个问题来了:在一块连通块 B 与 1 号节点所在的连通块相连时,怎么更新 B 内的节点?

可用链表维护,记录一个 nxt[i] 维护链表操作。

而且每个并查集维护三个信息:

  1. f[i],记录 i 节点的父亲,初始值:f[i]​=i;

  2. head[i]​ 记录 i 节点的连通块的节点中,编号最小的点;

  3. tail[i] 记录 i 节点的连通块的节点中,编号最大的点;

其中 head[i]​ 与 tail[i]​ 的 i 是连通块的根,即“老大”。

若要与 1 合并,还要先更新答案,而且每次合并时都是从大到小合并的,要保证 1 节点一直为根。

饥饿的lpb

原题链接

(感觉这个题有点水,比T1好想)

观察题目,我们不难发现,要得到最大美味值,狐狸应该先交错吃温度最大的和最小的饼干,其中如果能喝冰水或开水就更好了。所以我们给所有饼干按照温度排序,交替选择左右端点吃,如果先喝水再吃能获得更大美味值就更好啦。这样最大美味值就求出来了。(注意左右端点谁先开始,可能得到两个答案,再取个 max )

那么最小美味值呢,我们肯定按照温度顺序吃饼干。这样每两个饼干之间的差值就是美味度(如果不喝水的话)。比如我们记第 i 个饼干和 i−1 个饼干的差值为 T[i]​−T[i−1]​,则第 i+1 个饼干和 i 个饼干的差值为 T[i+1]−T[i]​,容易得到:如果不喝水,差值即为 T[n​]−T[1]​。此时即可分类讨论:

(1) 如果水温度在 [ T[1]​,T[n] ​] 之间,喝水与不喝水,对答案没有影响,答案就是 T[n]​−T[1]​。

(2) 如果水温度小于 T[1]​,我们又必须要喝水,答案再加上 W−T[1]​,即为 T[n]​−W。

(3) 同理如果水温大于 T[n​],答案即为 W−T[1​]。

综上,合并以上算式我们可以得到一个算式 ans=max⁡{W−T[1],0}+max⁡{T[n]−W,0}。

真理医生的难题

原题链接

可以使用分块。

当a[i]=1时,开方便不再有意义。加上每个数不大于le12,所以每个数至多被开方6次。

直接分块暴力,维护区间和和一个标记表示是否每个元素都为1。

如果每次区间开方只不涉及完整的块,不超过2√n个元素,直接暴力即可。

如果涉及了一些完整的块,这些块经过几次操作以后就会都变成 1,区间修改时跳过那些全为 1 的块即可。

体感一下复杂度和每个元素被开方次数有关,所以是可行的。

汉尼拔的晚宴

原题链接

1.因为n<=1e5,k<=100,所以O(nk)可以通过本题。

2.先考虑一下O(n*n)的做法:设 f[i][j] 表示前 i 分钟,当前煎的是正面,背面煎了 j 分钟的最小翻面次数。则有状态转移方程:

f[i][j]=min(f[i−1][j],f[i−1][j−1]+1) (i属于某个[l,r])

f[i][j]=f[i−1][j] (i不属于任何一个[l,r])  (即i位于不能翻转的时间段,这时没煎的面煎的时间没有增加 ,所以直接继承上一个区间的状态)

由第二个状态转移方程不难发现,对于两个区间之间的 i ,是可以直接跳过的。(背面煎的时间不变)

设 dpi,j​ 表示第 i 个区间结束时,没煎的面煎了 j 秒的最小翻转次数。

可以发现如果总共煎了 i 秒,其中一面如果煎了 j 秒,自然可以求出另一面为 i−j 秒。

在任意一个区间内,可以发现最多会翻两次面(翻转多次最终也可以转化为翻转一次或两次),所以分类讨论:

只翻一次面

        

1.由图可推出状态转移方程:dp[z,j]=min( dp[z-1,i-j-k] )+1

2.由于只能是在区间rz到lz之间翻转,并且结束时间为rz,所以 (rz−k≥lz)→(0≤k≤rz−lz),并且满足 rz​−j−k≥lz​ 。

3.因为所设状态为 区间结束时间 ,所以 i 无需枚举,为 rz​ ,方程则变为 dp[z,j]=min⁡( dp[z−1,rz−j−k] )+1  (0≤k≤rz−lz)

翻两次面

1.由图,可以得出转移 dp[z,j]=min⁡(dp[z−1,j−q])+2,同上 (0≤q≤rz​−lz​) ,且满足(lz​≤j−q≤rz​) 。

综上,所有状态转移方程如下(i为第i个区间):

翻转一次的情况会超时,所以考虑优化

根据翻转 一次 和 两次 的方程中,我们可以发现,每当枚举到一个新的值,都会和原来的值取更小值,最终会取得这一区间内的最小值。每次更新,都会更新更小值,这是符合 单调性 的,所以可以使用 单调队列 进行优化。

由于变成在一个范围内取最小值,所以 k 和 q 取 最大范围 ri​−li​ 。

具体的,我们可以将翻转 一次 的方程看作在 dp[i−1,ri​−j−k]​ 到 dp[i−1,ri]​​ 之间取最小值,将翻转 两次 的方程看作在 dp[i−1,j−q​] 到 dp[i−1,j​] 之间取最小值 ( ri​−j−k 化简后为 li​−j ,作为 出队条件 ,不用担心越界)。

经过进一步优化的状态转移方程如下( 0≤j≤ri ):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值