模因病毒
大乌龙:理解错题辣!
我理解的是两只猴子手拉手,结果是一只猴子用手拉着另一只猴子,当连着的两只猴子都松手时猴子才会掉下去。
这道题思路比较巧妙也比较常见:正难则反。
考虑正推,好像要带撤销并查集(觉得挺难,非要写应该也可以),面对这种删边问题,一般都是通过倒推的方法变为加边问题,往往会好做。
所以考虑倒推,问题转换为:通过不断加边,则每个点的掉落时间为它第一次与 1 号节点联通的时间,可用并查集维护。
但是,一个问题来了:在一块连通块 B 与 1 号节点所在的连通块相连时,怎么更新 B 内的节点?
可用链表维护,记录一个 nxt[i] 维护链表操作。
而且每个并查集维护三个信息:
-
f[i],记录 i 节点的父亲,初始值:f[i]=i;
-
head[i] 记录 i 节点的连通块的节点中,编号最小的点;
-
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 ):