1.CF613D Kingdom and its Cities
题意:给定一棵树,每个询问给出一些关键点,要求删掉最少的点使这些点两两不联通,无解输出-1。
思路:先判无解:只要有一个关键点的父亲也是关键点就无解。因为会被删除的点肯定是这些点中一些点的,所以考虑建虚树,然后树形DP。具体来讲,设表示当前有没有关键点与直接联通(若为关键点则),表示点的答案。转移时先,然后根据是否是关键点与的值(设为)分类讨论:
1.:
如果那就将点删去,;
如果那就将
如果自然不变
2.那与联通的点都得删,
最后就是答案,复杂度。
2.P2519 [HAOI2011]problem a
题意:一次考试共有个人参加,可能出现多个人成绩相同的情况。第个人说:“有个人成绩比我高,个人成绩比我低。”请求出最少有几个人没有说真话。(其实这就是原题面,这么简洁那我不直接复制过来)
思路:(十分人类智慧,不知道是怎么想出来的)首先定义一个人的排名是严格高于他的人数加1,然后就可以把每个限制改成:“我是第名,算上自己共有个人与我同分”,然后变成区间表示与第个人分数相同的区间,并把这个区间的权值定义为区间长度与所有的的个数的较小值。然后我们就把问题转化成了要选出若干不交的区间,最大化权值和。
我们发现,对做贡献的要满足,因此将所有区间按排序后就是一个前缀的形式,转移时二分出最大的,再维护一个前缀最大值即可完成转移。复杂度。
3.P6047 丝之割
题意:有若干条形如的弦,可以进行若干次操作,每次操作选定,会切断所有满足的弦会被破坏,代价为,求破坏所有弦的最小代价。
思路:斜优裸题(只可惜第一步没想出来)先考虑那些弦不会做贡献,很容易发现如果有两个弦满足那么如果要删弦就一定会同时删弦,那么弦就不做贡献。当我们把所有不做贡献的弦删去后,就不会存在一条弦的大于另一条弦的而较小,换而言之就是弦的都是单增的有了这个性质就很好DP了。
设为破环前个弦的最小代价,转移方程为
朴素的转移是的,我们考虑优化转移。我们发现,这个转移的形式似乎可以斜率优化,把当成,把当成,把当成,就和斜优的形式一模一样了,就可以愉快的套板子了。复杂度。
4.P6564 [POI2007] 堆积木KLO
题意:给定序列,可以任意删除一些数,删除后后面的位置会向前补齐,求最后序列中最多有多少个数满足
思路:我们记表示钦定最后在自己位置上时前最多有多少个满足条件的数,然后可得:。朴素转移是的,我们尝试把合法的变成一个前缀的形式。由可以推出,因此先排除不合法(即)的数,再按排序后DP,然后用树状数组维护最大值即可。复杂度
5.P4099 [HEOI2013]SAO
题意:给定一颗树,遍历方向为根到叶子或叶子到根,求遍历方案数。
思路:看到求拓扑序方案数首先想到设表示在的子树里拓扑序排名为的方案数,然后考虑合并时如何转移。,这个转移是的,但是我们发现这个组合数与无关,也就是说可以用前缀和优化转移,这样复杂度就是的了。注意转移时根据遍历方向的范围会不一样,需简单分个类。
6.P3160 [CQOI2012]局部极小值
题意:往的棋盘上填入~,每个数只能填一次。告诉所有是与其八联通的格子里最小的数的位置,求填数的方案数。
思路:因为所有格子里的数互不相同,所以在的棋盘上最多有8个这样的位置(即为局部极小值),这个数据范围提醒我们可以状压。又因为我们要填入数字,我们设DP状态为表示已经填了 ~ ,当前要填,填完后局部最小值的状态为,转移的时候我们分两种情况。一种是当前的数填到某给局部最小值的位置,这时直接枚举那个地方还没填数即可。第二种是填到一个不是最小值的位置,因为我们是从小到大填数的,所以局部最小值一定得在周围的数填入之前填入,这样就很方便预处理出每种状态下有多少点可以被填。但我们发现题目中说的是“所有”,这就意味这我们随便填会把一些不是局部最小值的位置变成局部最小值,这是只需大力容斥就行了(反正最多也只能填8个数),用一个不多的方案减去多1个的方案,加上多两个的……就行了。复杂度嘛,反正不高(主要是懒得算)。
7.P3600 随机数生成器
题意:给一个序列,中每个数是在中的随机数,然后给定个询问,求个询问的最大值的期望。
思路:(不愧是黑题)首先,如果一个区间完全包含了另一个区间,那它的最小值一定不大于它包含的区间的最小值,那么它就不做贡献。如果直接求期望没什么好方法,我们考虑把它转化为一个计数问题,最后除以就是答案。设为最终答案的方案数,然后最终答案为的方案数就是,这等价与每个区间的最小值都,即每个区间都存在的数,我们设表示在内选出个点,是的每个区间都被覆盖的方案数,然后就等于。然后考虑用DP算出。我们设表示前给位置放了个点,且第个位置必须放点,覆盖了所有左端点的区间的方案数。先预处理出和分别表示覆盖了的最左/右的区间,如果没有就是左侧最接近它的区间。因此,容易发现处在一个区间内,因此可以前缀和优化。然后就得到,然后也可以算出。复杂度。
8.CF79D Password
题意:有长度为的01串和个长度,每次可以将某个长度的子区间的取反,初始全是,求把给定的给位置变成的最小步数。
思路:(把状压和最短路结合起来的题目好像很罕见)看到就想到是状压,但是区间取反不好维护,我们考虑差分,即每个数异或上前一个数,那区间取反可以变成两个单点取反。因为只有个点最后为1,所以也最多只会有个数最后差分数组为。设为把01串变成状态的最小步数,因此其中表示只把取反要花费的最小代价。我们考虑每进行一次操作是把相隔为的两个位置取反,而我们取反再取反,就相当与对进行了取反,然后我们发现这很像一个最短路问题,每个点向与连距离为1的边,再用求一遍最短路即可求出。总复杂度。
9.CF662C Binary Table
题意:有一个的0/1表格,可以任意将一行或一列的0/1翻转,求最终最少有多少个1。
思路:我们发现只有20,就想到了状压DP。对于行的不同翻转状态只有种,我们自然想到了设表示行的翻转状态为时的答案。设每一列的状态为,再设辅助数组表示列状态为时翻转后最少有多少个1,即,那么。但这样的复杂度是的,明显过不了,我们考虑如何优化。我们考虑枚举答案,那么 ,但前面的还没丢掉。我们设表示有多少列的状态为,那么,换个写法就是,这个形式是不是跟长得一模一样?然后就可以愉快的套板子了。复杂度。
10.CF1428G2 Lucky Numbers (Hard Version)
题意:定义一个数的权值为:若第位(个位算第0位)为3的倍数,则产生的贡献,多次询问一个数被拆成个数产生的总贡献最大值。
思路:(什么神必多重背包+分组背包) 首先发现一个数位上是3还是6还是9是没有影响的,所以可以把6和9当成3来处理(减小思维难度及码量)。接着我们发现可以把这个数中的个每一位都是的倍数,然后考虑剩下的一个有数位不做贡献的数。先考虑这个数,我们把分成个数之和反过来看,即由这个数组成当前数,再把每一个数位拆开,发现这可以当作一个多重背包,第个物品的价值为,体积为,有个,但因为很大,所以采用二进制分组优化。再考虑剩下的一个数,就简单的当作一个分组背包来做,不过要注意这时也有可能还有的倍数的数位。复杂度。(还可以顺带把Easy Version写了,双倍经验)
11.CF1393E2 Twilight and Ancient Scroll (harder version)
题意:个字符串,每个字符串可以删掉一个或者不删,问有多少种方案是得字典序不降。
思路:(这题明明就是考串串科技)首先可以想到一个朴素的的DP,设为第个串删第个字符使得这东西字典序不降的方案数,若不删则。然后考虑优化转移。首先想到,可以把字符串想作一个数,比它小的数是一个前缀的形式,那字符串也是一样,因此把字符串删掉一个之后的个字符串排序后转移就可以用前缀和优化了。但是这样空间显然开不下,时间上也过不去。我们采用贪心的思想,考虑相邻的两位,他们的前缀是相等的,如果这两位相等,那删掉后的字符串也相等,若不相等,就可以比出大小,最后稍稍处理一下删第个字符的情况就可以了。然后我们考虑不同字符串之间怎么高效比大小,这时就可以用哈希+二分,找到两个串第一个不相等的位置,就可以比大小了,单次,共次,因此总复杂度。(又是一道双倍经验的题,好耶)
12.CF585F Digits of Number Pi
题目:给定数字串,求存在长度不小于的子串是的子串的数字串的数量。
思路:(为了这道题我甚至专门学了半天的SAM)。首先看到第一反应肯定是数位DP,但又因为与字符串匹配有关,自然就考虑上AC自动机或SAM,而我写的是SAM的做法。设表示当前在第位,在SAM上为第个节点,当前已匹配的字符串长度为,表示有没有顶到上界,表示目前长度合不合法。转移时枚举下一个选的哪一个数字,若长度已合法或SAM上当前节点有这个儿子则可直接转移,否则不断跳直到有这个儿子或跳到了1号节点为止,然后再转移。复杂度。(又一次SAM忘开两倍空间了,警钟敲烂)
13.CF1188C Array Beauty
题意:定义一个序列的权值为两个数之差的绝对值的最小值,求长为的序列的所有长为的子序列的权值之和
思路:首先肯定是对数组排序。我们发现,这一题的值域很小,那做法可能和值域有关。答案的最大值肯定不会超过,因此我们考虑枚举答案,然后DP计算权值的方案数,然后直接将方案数相加即可。然后设表示当前在第个数且选第个数,已经选了个且满足条件的方案数,所以,然后用前缀和优化就是的了。总复杂度。
14.CF1179D Fedor Runs for President
题意:在树上删除一条边后,求最多能形成多少条简单路径。
思路:(感觉这题的难度比前几题上了一个台阶) 大体做法:树上斜率优化。(实在难以理解) 首先只考虑加一条边后会多出来多少条路径。假设加入的边为,设为上一点不向路径延伸的子树大小,那
要让答案最大,我们就要选一条路径使尽量小。
我们设为当前点,然后计算每一条经过的路径的答案。设为的子树中让上式最小的路径,则其中即为。
求出这个后,考虑如何将两条路径合并。先朴素直接枚举两个儿子来转移,即
这样一次转移是的,但看到这个二次式我们尝试用斜率优化。我们枚举一个,然后求出最优决策点。枚举两个点假设比更优,那么有
化简后可得
再变形可得
因此当时,
然后再注意时不等号变号,以及特判一下等于即可。还有就是我们按大小先给所有儿子排序一遍后转移就很方便了。
总复杂度(感兴趣的话可以自己证一下复杂度,我太懒了这里就不证啦)
upd:其实很好证。
15.CF115D Unambiguous Arithmetic Expression
题意:给一个不含括号的表达式,求有多少种方法给其加上括号使得其仍合法。
思路:(一眼区间DP,只是) 不过好像区间DP减减枝可以过,但我没试。设表示考虑到第个位置,前面已经有个左括号为匹配,当前填的是"("还是")",然后考虑转移,方向是。先考虑,那么有(在后面加一个左括号就是个左括号未匹配),(在自己这里再添一个右括号)。然后是,那么有
然后这道题就做完了。复杂度
16.P3349 [ZJOI2016]小星星
题意:给定有个点的数和无向图,求有多少种标号方案使得树上每一条边都在无向图中存在。
思路:考虑到求编号,我们设表示子树内,标号为,且使用了中的标号的方案数,但转移时要枚举子集,复杂度是的,过不去,我们考虑优化。首先很容易想到把标号集的限制去掉,但这样会出现重复编号,那容斥不就解决了吗?具体来说,对于每个求出每个点的编号都在内的方案数,然后用的方案数减掉的,再加上的然后这题就做完了。复杂度
17.P2612 [ZJOI2012]波浪
题意:定义一个排列的波动值为相邻两数之差的绝对值之和,求所有长为的排列波浪值不小于的概率,保留小数点后位。
思路:(上古时期模拟赛考过简单版,不出意外获得了0分的好成绩) 看到绝对值不好处理,一个常见的套路是考虑从小到大插入每个数依次计算贡献。我们发现一个数作的贡献只和前个数组成的连续段情况以及和边界的关系有关。我们设表示考虑到第个数,一共组成了个连续段,总贡献为,有个连续段与边界相连。然后考虑转移。
1.不与任何连续段相连,那么连续段数+1,贡献减少,边界情况不变,有种方案。
2.一边与边界相连,另一边不与连续段相连,那么连续段数+1,贡献减少,边界上的,方案数有。
3.一边与连续段相连,另一边不与连续段相连,那么连续段数不变,贡献不变,也不变,有种方案。
4.一边与边界相连,另一边与连续段相连,那么连续段数不变,贡献,边界的,有种方案。
5.两边都与连续段相连,显然连续段数减少1,产生的贡献,边界情况不变,有种方案。
总复杂度。
坑点:小数点后30位要用__float128,边转移边除以,以免除以时爆精度,还有要用滚动数组。
18.P4383 [八省联考 2018] 林克卡特树
题意:在树上选出条不相交的链使得链的边权和最大。
思路:WQS二分+树形DP。看到恰好多少条就想到了WQS二分,二分选出一条链的代价,然后用树形DP算出选出多少条链最优。具体的,设表示在的子树中,点的度数为0/1/2,最后的0/1表示是权值还是选了几条链。转移时:
复杂度:。
19.P1721 [NOI2016] 国王饮水记
题意:给定一个序列表示每个城市的水量,保证互不相等,可以进行次操作,每次可以任意指定一些位置并把每个位置变成它们的平均数,求1号城市的最大值(保留位整数)。
思路:(看完这道题38页的PPT,我整个人都被震撼到了) 首先可以找一大堆性质。比如,比1号城市小的水量肯定没用;合并时一个一个合并比一起合并更优;一个城市最多和1号城市联通一次;每次合并一定包含1号城市;当次数不足以每次都一个一个合并时,一定是将排序后的连续一段。然后就可以DP了。设表示前个位置合并了次的最优值,那么。这样的复杂度是的,然后发现决策点是单调的,这样就可以斜率优化,复杂度,但我们发现这还过不去。还有性质是选择的区间大小不升,并且由每个互不相同可以推出长度不为1的区间不会超过,其中 (反正我不会证),然后复杂度就是。如果在前面DP时不直接使用高精度运算就可以把复杂度降为。点评:毒瘤题
20.P3734 [HAOI2017]方案数
题意:一个人从走到,每一步可以或或,其中有个障碍点,求方案数。
思路:考虑容斥,用全部的走法减去不合法的走法。先考虑怎么求全部走法。设表示走到点满足的方案数,转移时
先把所有关键点按字典序排序,然后依次枚举每个障碍点,设表示不经过任何障碍点到达的方案数,因此:
其中表示从障碍点到障碍点的方案数,则
复杂度。
21.CF1119F Niyaz and Small Degrees
题意:一棵大小为的树,有边权,设表示要满足所有点的所要删掉的边的边权和的最小值,求出到
思路:先考虑对于每个计算答案。设表示向上连的边删或不删时的最小代价。转移时,对于的每个儿子,有两种贡献,表示删掉的贡献,表示不删的贡献。我们考虑先取所有的,用堆来维护所有的,然后选最小的一些把替换掉,这一步可以用堆维护。单次复杂度。
然后考虑正解。如果从小到大考虑每个,那么一个的点对是没有贡献的,对于每个点只需考虑的情况,这样的量级是的。我们将的点视为无用点,其他为有用点,然后从每个有用点开始dfs,把无用点视为叶子,这时每个无用点的,它对它相邻的有用点的贡献即为,然后像暴力做法一样加入有用点的贡献,最后再加上一直弹堆顶到堆中元素为须删掉的边数时,堆中所有的和就是答案。注意更新答案后要撤销加入的有用点的贡献,并撤销不断弹出堆顶直到堆中元素符合要求时删除的无用点的贡献,需要用可删除堆维护。总(均摊)复杂度。(有个智障调了一上午结果发现可删除堆写错了,警钟敲烂)
22.P3643 [APIO2016] 划艇
题意:有个位置,每个位置上可以选一个在中间的数,并且要大于它前面任意一个选了的数,也可以不选,求方案数。
思路:先考虑朴素DP。设表示第个位置选了的方案数,那么
我们发现如果把第二维看作自变量的话,那么可以发现这是一个多项式,而每求一次前缀和次数+1,所以最高是次多项式,那么我们带入个点值进去就可以得到答案。
复杂度。
23.CF1268E Happy Cactus
题意:给定一个无向仙人掌,边权互不相同,定义是好的当且仅当存在从到的路径满足边权单调递增,对于所有求出有多少是好的。
思路:首先考虑如果是一棵树怎么做。我们从大到小加边,设为答案,每次加的边的两端在之前必然无法到达,所以能到的点多了和能到的点,即。
然后考虑一般的情况。我们发现,有可能加边的两端已经互相可达,这时会出现重复,而这种情况只可能出现在最小边的两端可以合法到达最大边的环中,设最大边的一段为,那贡献要减去加入这条边时的贡献,即,其中为加入这条边时的贡献,即。先求出点双然后判断每个点双是否合法即可。
复杂度。
24.CF1239E Turtle
题意:给一个的棋盘和个数,给出把这个数填入棋盘的方案,使得从左上角只向下或右走走到右下角遇到的数的和的最大值最小。
思路:(思维量巨大题) 先找一些性质。首先,假设选好了一行的数,那么肯定是第一行从小到大,第二行从大到小。假设在第列转向的答案为,那么,其中,即向右移一位的改变量。容易知道是递增的,而一开始的有可能小于0,那么只有可能在或是取到最大值。接着,假设我们选定了,那么我们就要选出个数使得最小,而的值是确定的(记为),假设一个方案,那,所以最接近的一组方案是最优的。这样,我们枚举,就得到了的做法,但明显过不了。我们要让最大值最小,那么一定要让做贡献的数尽量小,所以一个很直观的想法是把最小值和次小值放在和,这样就可以降低复杂度了。
复杂度。
25.P1295 [TJOI2011] 书架
题意:给一个序列,要分成若干段使得每一段长度不大于,最小化所有段的最大值之和。(其实这题本来不是这个题单里的)
思路:(的做法太神仙了) 首先可以很简单的想到一个的DP:设表示为当前段末尾的最小和,则。因为有最大值,我们考虑找找单调性。首先,如果,那么,而显然是单调递增,那这个时候从转移一定比从转移更优,所以我们很容易用一个单调队列(记为)来记录可能对答案做贡献的位置。然后我们考虑如何计算贡献。因为队列里的值是递减的,即,那么每个的贡献就是,这时我们还需维护。为了保证复杂度,我们可以用两个单调下降的栈来维护,每当左或右端点到了中点就重构,这样复杂度就是的了。
26.P8352 [SDOI/SXOI2022] 小 N 的独立集(其实这题本来也不是这个题单里的)
题意:给定大小为的树,每个点点权可以为,求最大权独立集大小为的方案数。
思路:一开始以为是普通的树形dp,后来才发现是dp套dp。首先考虑如果是直接求最大权独立集大小,那么就是设表示点选/不选的最大值,然后,,而在计数时,我们考虑将和记入状态,设表示子树中分别为的方案数,这就是一个树上背包的问题,只不过复杂度较高。我们发现这个状态本身就是的,需要优化,于是我们改变定义,设表示是否强制不选点的答案,我们发现有一些性质,比如,那么我们就可以简化状态,记表示在的子树中,为,为的方案数,每次转移时有,这样一来复杂度就是的了。
27.P8329 [ZJOI2022] 树(同上……)
题意:定义两颗树是好的当且仅当第1棵树每个点父亲编号小于它,第2棵树每个点父亲编号大于它,每个点恰好在一棵树上是叶子,求对1~求方案数。
思路:(不会容斥,好似) 首先考虑设表示第1棵树非叶集合为的方案数,第二棵树为,那么很容易推出
但是和并不方便直接求,我们考虑容斥。设表示第一棵树非叶集合的方案数,同理,那么可知
这样似乎比之前的恰好更好处理一些。于是我们设表示的方案数。转移时根据是属于还是还是都不属于进行分类讨论即可。
复杂度。
28.P7519 [省选联考 2021 A/B 卷] 滚榜
题意:给出数组以及数组的总和,求有多少种标号方案,使得按从小到大依次加入后新加入的是当前最大的。
思路:(学到了一个很新的科技) 我们考虑DP的状态应该与那些有关,首先是已经加入了的位置有哪些,这个是的,当前加入的数的以及总和,这样的DP固然带,显然不行,我们考虑怎么去掉一维。我们可以发现,一旦确定了顺序,我们就可以贪心地使每次的尽量小,这也启示我们可以试图去掉当前枚举的这一维,只需保证不降,即的差分数组非负。但是有一个很严重的问题是是有后效性的,于是我们可以用“费用提前”的,把当前选的数对后面的数的影响算出来并减掉,这样就可以避免有后效性了。时间复杂度。
29.P8497 [NOI2022] 移除石子
题意:有堆石子,每一堆石子数量在之间,每次操作可以拿走一堆里个石子或在长度的区间里每一堆石子拿走一个,求添加恰好个石子后能把所有石子取空的方案数。
思路:(不愧是NOID1T2,听同学讲后又看了Wei老师的博客才搞懂)
首先考虑如何检验一个局面是否合法。首先考虑简化操作。第二个操作显然可以把长度的区间拆成由长度为的区间拼起来,那么我们就只用考虑这4种操作。其次,我们可以使每一种长度的操作的次数,因为做相同的操作可以直接用操作1代替。于是就可以考虑DP,设表示之前的操作二,有个可以延伸到,有个必须枚举到,有个必须枚举到,是否可行。转移时枚举从开始的操作数量,再枚举个中实际延伸到的数量,判断是否或就是合法的。
这时我们发现,可以将这两维状态合并。我们直接钦定有多少个操作延伸到了即可。于是,我们改成设表示之前的操作二,有个钦定延伸到,有个钦定延伸到,是否可行。转移时同样枚举从开始有多少个操作二即可。
这个时候的范围是的,我们考虑缩小范围。我们发现,如果同时进行了一次的操作,那这等价于一次操作1和下一个位置的的操作,于是就降到了。接着我们枚举从延伸到且在处长度的情况可以发现这些可以用不超过2次操作二代替,于是范围就是的了。
接着考虑的情况。我们发现恰好不好处理,于是改为至多,再容斥一下下,即添加小于个石子有解,添加个后无解的方案数。首先无影响,只有或,而当时可以归纳证明若添加小于个石子有解,那么添加个石子也一定有解(k=1除外)。于是我们设表示使最少需添加的石子数,转移时枚举,然后从至少要添加的石子数转移到即可。
接下来就是对计数。因为只有9种状态,于是我们考虑DP套DP。设表示这9种状态取值为的方案数。为了方便转移,我们设表示从状态为的开始,令,转移到的状态。由于中,因此,这样子贡献就比较好统计了。然后(不知道怎么样子就) 发现的操作是等价的,于是就可以计算了。
最后考虑,因为有~共102种取值,但实际只有种状态,可以通过。
复杂度:。(写得好累……有1302个字,比作文还长)
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探