多校A层冲刺NOIP2024模拟赛19

多校A层冲刺NOIP2024模拟赛19

其实不太想写博客,但还是从今天开始坚持写吧。

T1 图书管理

对于这种一边大一边小的问题,一般套路是大的设为 $ 1 $ ,小的设为 $ -1 $ ,这道题也是,这样之后去扫一遍,两端的前缀和值一样即可。

T2 两棵树

新学到的一个重要 $ trick $ 是: $$ 连通块的个数 = 剩下的点 - 边的个数 $$

前提是这是一个从树删下来的图。

然后分讨一下就行了。

T3 函数

主要有一个性质,只要有任意两点满足题目中的式子那么就一定有答案,因为我们可以先找出两点(不一定挨着)满足 $ ( x_i \oplus a ) - b \le 0 , ( x_j \oplus a ) - b \ge 0 $ ,然后我们直接找到他们的中点 $ mid $ ,这时无论 $ ( x_mid \oplus a ) -b $ 是什么,他总能和一边匹配成为新的合法的二元组,这样二分直到两者相邻。然后确定是否有答案时直接找到 $ x_i \oplus a $ 的最小值和最大值即可,用 $ trie $ 维护一下。

T4 编辑

这题非常的奇妙,先是对着别人的码 $ 贺 $ 过了,然后才真正理解为什么这么写。

首先有一个 $ O(n^3) $ 的 DP,就像 碱基配对 那道题一样,不过需要枚举起点。

然后注意到 $ k $ 很小,我们从这下手,考率优化状态: 每进行一次操作我们都可以让一个序列在匹配的基础上多加一个或者多删一个,因此两者的长度差最多为 $ k $ ,然后设置状态为 $ f_{i,j} $ 表示 进行了 $ i $ 次操作,两者长度差为 $ j $ 时, $ S $ 串最多匹配了 $ f_{i,j} $ 个。

然后对于每一种状态,我们已经确定了下次匹配的起点,S的起点是 $ f_{i,j} +1 $ ,T的起点是 $ f_{i,j} + j + 1 $ ,所以我们先加上不需要操作的,即可以直接匹配的,直接求一个最长公共前缀即可,然后考虑用三种操作去转移:

1、 删除:

image

图中白色的是已经匹配好的,然后我们要去删除一个S后面的点,这时会导致 S 匹配的个数 + 1 ,T的不变,两者的差 - 1,多进行了一次操作,所以有转移 $ f_{i+1,j-1} ← f_{i,j} + 1 $ 。

2、 添加:

我们给 S 中添加一个,肯定让添加的这个去和 T 中的一个匹配,所以 S 的匹配数不变,T的匹配数 + 1 ,两者的差 + 1 ,操作数 + 1,所以有转移 $ f_{i+1,j+1} ← f_{i,j} $ 。

3、 修改:

我们给 S 中的一个修改去和 T 中的一个匹配,此时两者的匹配数都 + 1 ,差不变,所以有转移: $ f_{i+1,j} ← f_{i,j} + 1 $ 。

最后统计答案时统计 对于每一个 $ j $ ,找一个最小的 $ i $ ,使得 $ f_{i,j} = size_S $ 即可。

然后你发现不对,输出之后会发现有一些 $ f_{i,j} \gt size_S $ ,那不就是说我在 S 中匹配了比 $ size_S $ 还多的字符吗,这怎么可能,但是把这些都计入答案的话就对了。

image

对于上图这种情况,我们已经枚举到了白色的部分已经匹配的状态,然后会去加一个 $ LCP $ ,然后后面的 a 就匹配上了,然后如果我们要计算以 $ T $ 中白色部分最后一个为终点的方案,那么他最少的方案可能是把 $ S $ 中最后一个 a 删了,但是在上面的转移中我们没有考虑这种情况,因为我们直接加了 $ LCP $ ,是人为的强制匹配,所以还需要删回去,那么其实上面的删除操作可以进行这种转移,但是他会使 $ S $ 中匹配的个数 多于 $ S $ ,所以这部分其实是合法的,直接加上即可。

或者Qyun还有一种写法:


f[i+1][j-1]=max(f[i+1][j-1],f[i][j]+(f[i][j]!=lens));//shanchu
f[i+1][j]=max(f[i+1][j],f[i][j]+1);//gai
f[i+1][j+1]=max(f[i+1][j+1],f[i][j]);//jia

这样直接加上 = 的时候就行。

posted @ 2024-11-08 08:00  lzrG23  阅读(36)  评论(0编辑  收藏  举报