杂题选做

1. CF1499F Diameter Cuts

乐了,连三方的做法都想不到了,可见我的 dp 有多菜 /kk

贺了之后感觉是世博题啊?

首先很显然 dp 状态可以设成 fp,x 表示割出的含 p 点的连通块里边最深的点深度为 x 的方案数。

问题是怎么转移呢。我一开始想的是枚举最大值是哪个,但显然会算重,是假的。考虑类似树上背包的想法,在转移时临时加一维变成 fp,is,x 表示 p 的子树,目前到第 is 个子节点,目前的最大值是 x。只要考虑新的一个子树里面截多少深就可以了,刷表法转移,开一个数组记录变化量,并在原数组上更新 f

对状态 fp,is1,x,枚举第 is 个子节点 v 的截深 y,会有以下三种情况:

  • fp,is,xfp,is1,x×fv,y (ymin(kx,x)1)
  • fp,is,y+1fp,is1,x×fv,y (xykx1)
  • fp,is,xfp,is1,x×fv,y (表示截掉整个 y 的子树)

暴力 dp 的状态要枚举 px ,转移要枚举 y ,复杂度是三方的。因为是与深度相关的 dp ,而且对一条链的情况满足优秀的性质 fp,1=fv,0 ,所以考虑用长剖优化。可以把枚举 p,v 和转移 y 的复杂度合并到 O(n),枚举长链上的 x 还要 O(n) 的复杂度,于是就可以在 O(n2) 的复杂度内通过。

关于长剖,由于上述性质,做完重链相当于已经有了 fp,1,x(x1),我们只需要考虑 fp,1,0 的情况。相当于是必须断边 (u,v),随便加一下即可。

2. CF855G Harry Vs VoldemorT

3300?2300!

先考虑只有一棵树的情况怎么做。在 w 处计算贡献,贡献即为删除 w 点和其相邻的边所形成的连通块的两两乘积的两倍,可以通过维护连通块大小的二次方和来方便计算。

扩展到基环树,对于不在环上的点和树的情况没有区别。对于在环上的点来说,把环作为一个整体分三种情况考虑:

  • uv 两点都在环上,对每组 (u,v)w 一共有 siz2 种方案。
  • u,在环上,v 在外面,对每组 (u,v)w 一共有 siz1 种方案。
  • u,在环上,v 在外面,对每组 (u,v)w 一共有 siz 种方案。

注意到题目里是无向图,所以把环扩展到边双连通分量也是一样的。本质上是要求过一个连通分量的路径有多少条,于是参考树的情况,维护一个联通分量的大小和所有连出去的子树大小的平方和即可。

暴力模拟缩点,使用并查集维护每个联通块的最上端点,在暴力跳的过程中减去缩掉的点的贡献,缩完再加上新点的贡献即可。

3. CF1455F String and Operations

个人感觉这个 2800 甚至比大部分 2200 的 dp 还要常规不少 /kk

这个 “原来在 i 位” 的条件比较麻烦,不妨试着分析一下性质。观察得到,进行完前 i 次操作后,原来在第 i+1 位上的数只可能在 ii+1 位上。

很容易想出一个朴素 dp: dpi,0/1表示做完了前 i 次操作,原来的第 i+1 位现在在 i/i+1 位的最优解。 从 dpi1,0/1 转移。

但因为有大量的字符串比较,复杂度是平方的,需要卡常才能过。注意到修改完第 i 次后,串中第 i2 以前字符的都确定了。

而在转移来的状态相同时,第 i 次的操作不同只可能影响到 i2 以及后面的位置。考虑改良状态设计,只保留字符串的 i1i+24 位。如果 dpi,0dpi,1i2 位之前有不同,只用保留更优的并禁止另一个转移出去即可。细节有一点烦。

4. CF1481E Sorting Books

有点意思的题。

考虑到扔一个数的顺序是无所谓的,因此移到右边可以视作把这个数扔到边上需要的时候再拿回来。问题相当于求最多有几个数可以留在原位。

一眼一个假 dp:处理出每种颜色的最左端点,最右端点,出现个数。然后做最大不相交。设 fi 表示到 i 的前缀最大有多少个可以留在原位。

但这样是假的,连样例也过不了。注意到可以从左边直接取一些点黏在最右边。比如说样例 2 ,直接把最左边的 1 放到最右边即可。

如果直接做会 WA on 3,我不会,就去贺了,得到一组数据:2 3 4 5 6 2 2 8 2,答案应该是 2 而不是 3。具体的操作方法是把最左边的 2 抽到右边,然后再把 8 丢出去。因此存在一种可能,一部分原串的前缀接到后缀后面,并把非目标颜色踢出去。容易知道这种情况只会出现 1 次。

我们考虑后缀 [i...n],钦定目标颜色是 ai,留在原位的最大数量相当于 fi1 拼上后面与 i 同色的个数。预处理 f 后从后往前枚举 i 即可。

5.P4107 [HEOI2015]兔子与樱花

先考虑只记 ci 不计度数的情况,一眼的最少连通块划分。

我一开始想了个很烦的平衡树启发式合并假做法,看来是数据结构学傻了。

一般来说,如果单点费用为 1,那有较大的可能是贪心或反悔贪心。这个问题可以转化为求有多少个点不用被并到 fa 上去。

考虑一个菊花图,中间点肯定是要合并尽可能多的周围点,那很显然就是先把小的合并上去再合并大的。对一般图来说,我们维护子树顶上连通块的大小,按它从小到大贪心。

计算度数的话就按 ci+otdi 贪就行了,注意一些维护细节。

6.P4694 Raper/CF802O April Fools' Problem (hard)

很 Educational 的一道好题。

首先考虑合法的条件,最优策略显然是先进 a 的盘子也要先进 b 。因此不难想到一个费用流模型。Sai 连边,费用为 aiTbi 连边,费用为 biai 向所有 bji 连边,无费用。

看到数据范围考虑模拟费用流。比较麻烦的是 k 的限制,但显然答案随 k 是一个下凸函数,可以用 wqs 二分优化掉。现在问题转化为了无流量为 k 限制的最小费用流。很显然每条增广路径的费用都必须 <0

能够产生费用的边无非是 SabT ,而中间 ab 的边是不产生费用的。 使用增量法的思想,考虑从 n1,在左边新加 aibi 所能产生的贡献。使答案更优有两种可能:产生一条新的增广路或是产生一个负环。

产生新的增广路的话,必须是 ai 和右边费用最小的 bi 匹配。如果是负环,有两种可能:SABASSABTBAS 。第二种情况中,从 TS 一段费用必定是正的,否则当初就不会选,这个环严格劣于只走 ST。因此只需要考虑第一种负环。对每个有入度的 b ,退流的费用就是连进来的 a 的价值取负。可以用堆维护。使用 wqs 的时候直接把每个 ai 的费用都减去 cst

另外这道题不要用实数二分,会被卡常。

7.CF1591E Frequency Queries

一眼离线询问,然后平衡树维护。但这是 Div 2E,一般不可能这么码,而且以我的常数, 1log 的 FHQ 是不可能过 1e6 的,于是考虑换个做法。

我们把所有的颜色按照出现次数从小到大排序。记录每个出现次数颜色的开始位置。在经过一个点时,操作相当于把这个颜色的出现次数增加 1。如果 p 点的颜色原来的出现次数为 x ,则把这个颜色 swap 到出现次数为 x 的最后面,然后把出现次数为 x+1 的颜色开始位置 1 就行。

这题的难点应该就是要不敢写平衡树?

8.CF698F Coprime Permutation

大概是结论题?

打个表先。猜测一个结论,排列中质因子集合相同的数可以互换。又注意到 n=10 的时候 17 也可以互换,猜测 1>n/2 的质数都可以互换。因此开桶记录每个基底(定义基底为一个数的所有不同质因数乘积)有多少个数,再记录一下 >n/2 的质数个数。最后阶乘起来。

看起来很对,美滋滋地一交,会发现 WA on 12(比如我),而且死活想不出怎么错的,于是又只能贺。

2 个结论还可以加强,对于 n/2 的质数,如果 np1=np2 ,则 p1p2 的倍数可以整体互换。这个在小数据里是看不出来的。由整除分块的性质,只有当 p1,p2n 时才有可能满足相等的条件。因此可以互换的只能是每个数的最大质因数。开桶记录商为某个值的质数有多少个。

考虑 ai 已经确定的情况。如果 iai 的基底除去最大质因数仍不同,则一定不合法。如果它们的最大质因数不满足 np1=np2 ,那也不合法。数组记录 iai 最大质因数的对应关系,如果已有匹配且冲突则不合法,如果是第一次匹配,那就把下表为商的那个桶的大小减一。在任意合法的情况,因为都限定了一个同基底点的位置,所以都要把基底为它的桶里减一。

9.P4587 [FJOI2016]神秘数

注意到值域比较大,所以不能无脑背包。

考虑暴力怎么做?为了方便设 a 数组从小到大有序,并记 s 为前缀和。如果前 i 个数能表示 0si 区间的所有数,则 ai>x+1 和不合法是充要条件。如果前 i 个数能表示的数不是连续的呢?假设它到 ai1 之前能表示的范围都是连续的,第 ai 开始不连续,则这两段区间必然是 1si1aisi,因为 ai+1ai ,所以加入 ai+1 也无法表示 (si+1,ai) 区间。

因此如果 a 按从小到大排序,答案即为第一个满足 si+1<ai+1si+1。考虑怎么快速找到?由上式可以推得 2si+1<si+1 ,因此上一个可能不合法的位置 s 至少要减少一半,二分即可。最多二分 logA 次,一次查询的复杂度是 logn×logA 的。

注意到还需要较快速地使一段区间里的数变有序,可以用权值主席树解决,把二分换成线段树上二分即可。

你敢信我三天前就口胡好了就差一个主席树板子但一直在打炼金工房直到今天才写掉 😅

10.AT2000 [AGC002F] Leftmost Ball

炼金工房实在是太好玩了,又玩了一周卷了零题。 😅 另外 A20 角色在游戏内好丑,全靠宣传画骗我进去,还他妈晕 3D 了,rmq 退钱。

很好的 dp,把钦点玩到极致了属于是,再给我五年时间也不可能自己想出来。

符合条件的序列一定有 n 个白球,每种颜色有 k1 个色球。而且每个前缀的白球数一定大于颜色数。

在最终序列中一位一位考虑填啥做线性 dp 肯定是不现实的。自然想到考虑一个新的颜色的所有点加进来以后会对原序列产生哪些变化。而且在原序列里插入很麻烦,那不妨扩展一下思路,直接将新的颜色填进长度为 nk 的最终序列里面

感觉比较关键的是每个颜色没被染白的第一个点(下简称一号点)。我们可以钦点每种颜色对应的白点是按一号点的顺序排列(比如说一号点最前面的颜色对应最前面的白点)。在加入新颜色时,钦点这个新的颜色的白点在第一个合法位置,且中间的空位全都要留给后面的颜色放它们的白点。(注意计算方案数时还要乘上对应的颜色选法,也就是说第 i 种颜色就要乘 ni+1)。

中间的空位全要放白点的这个条件启示改进状态设计,设状态为 fi,j 表示放进去了 i 个白点和 j 种颜色的方案数。如果放白点,则钦点放在第一个空位。如果放彩点,则先选实际使用的颜色,再钦点它的一号点放在目前的第一个空位,后面的 k2 个随便填。(因为空位个数随 i,j 而固定,所以可以直接乘上一个组合数计算。)

11.P4786 [BalkanOI2018]Election

和 P8304 基本一致,可以考虑一下双倍经验。

相同的剧本又来了,我又打了几天炼金工房并卷了零题 😅

先考虑对整个序列进行询问怎么做,将题目中给的 01 串抽象成括号序列和折线图,容易发现合法序列的充要条件是起始点最低且结束点最高。很显然我们只会删除下括号(也就是 1。设折线图上每个点的高度(也就是把序列换成 +1/1 之后的前缀和)为 hi。对于每个前缀 i 都必须满足在第 i 位之前至少删除了 hi1。对于每个后缀 i 都要满足在第 i 位之后至少删除了 hihn1

转化成了前缀/后缀限定至少放几个,问最少地总放置个数的问题,但看着还是有点麻烦,不妨先精简一下,只保留必要的限制。

hm6I1.png

考虑贪心地放来满足后缀限制的需求,就是说从后往前考虑,直到不满足要求再放,这样可以满足放的所有点都尽可能在前面。图中就是在“至少要放 1 个”处放 1 个,在“至少要放 2 个”处再放 1 个。贪心的原理是放在越前面能影响到的前缀限制能更多。

再考虑如何满足前缀的限制。从左到右考虑每一个前缀限制,设它至少要求要放 Bi 个而在第一次放的时候从 1i 已经放了 Ai 个。则在前缀中必须补放 max(0,BiAi) 个。感性理解这种构造方法和这题的删 1 操作是可以完美对应的,但具体证明不是很会。

不难知道 Ai=maxAllmax(hji)Bi=hi ,又第一次操作放的个数显然是 maxAllhn 个,化简一下最终的答案就是 min(hi+hnhji,0)。在原 +1/1 序列里的意义即为任意取一对不相交的前缀和后缀。这不就相当于区间和减去区间最大子段和吗?线段树维护即可。

12.CF1063F String Journey

先把串倒过来,这样从前往后就是从小到大,比较舒服。

很显然最优情况下的字符串长度必然是每次增加 1

考虑一个 dp,设 fi 表示以 i 为结尾的最长合法字符串长度为 fi。转移取满足 j+fj<isuf(j,fj)=suf(i,fj)suf(i1,fj)jfj 最大的转移而来,把 fifj+1 即可。二分每个 fi 并使用主席树维护 SAM 上的子树最大值(倍增到最靠近根节点的 lenfi1 的节点,查询 maxj 那个版本中这个子树里的最大值是否 fi1)可以 2log 做。

但这样是过不了的,参考题解可知一重要结论:fi1fi1。因为从 i 位的最优解删掉第 i 位的字符就可以变成一个 i1 位的合法解。因此,可以得出 ifi 是单调不降的,而 j 要满足的范围也可以说是 jifi 。(因为 fi=fj+1)。每次从 fi1+1 开始枚举 fi,加入所有 ifi 的新 j。这样可以省去主席树,又因为 fi 增加的次数不会超过 O(n),所以所有 fi 变化的次数也是 O(n) 的。总复杂度 O(nlogn)

13.P1295 [TJOI2011]书架

感天动地,随机签派终于抽到简单题了!

想 grand msfs 发现写完了还没进游戏,rmq退钱

fi 表示以 i 为结尾的最优值。预处理 li 表示最小的从 lii 的和不超过 m 的位置。(当然可以二分,但显然 li 是单增的,用指针更好写)。转移方程为 fi=minliji(fj1+max(j...i))

经典套路,使用单调下降的单调栈来维护到 i 为止所有的后缀最大值。栈顶值为 x 代表从栈顶到它之前那个元素的位置的一段,到 i 的最大值是 x。若这个栈顶被 pop 了出去,相当于是把这一段到 i 的最大值增加了 aix,相应的从这一段转移过来的费用也增加了这些。使用支持区间修改和查询最小值的线段树维护从每一位上转移而来的费用即可。

14.CF356E Xenia and String Problem

历史遗留问题之一。当初贺都贺不懂,但现在也只是贺懂了而已。

“朝算贡献,夕死可矣。” -V.A.

很显然合法的 g 串长度只能是 2k1,因此 g 串的个数是 O(nlogn) 级别的。可以从小到大枚举每个可能是 g 串的子串,就可以确定原序列的价值。

考虑怎么在只修改 1 个字符的条件下把一个串变成 g 串。如果它的左半边和右半边相等,那只能改中间。如果左半边和右半边不相等,只有在不同的字符只有一个时才可以通过修改改成 g 串。因此可能的修改方案数是常数级别的。枚举每个长度为 2k1 的串,如果一种方案可行就把这种方案的贡献加上 leng2

再处理出原来经过每一位的 g 串的价值,如果一个串是 g 串就在这一段区间上区间加上贡献值,差分数组维护。对每个修改方案的答案就是 原串价值和 - 原串经过这一位的串的价值和 + 修改所得的新贡献。

15.AT2663 [ARC079D] Namori Grundy

gk 一百年前给的题,不过是 Shitty Problem.

每个点的入度为 1 意味着这是一棵外向基环树。每个点的权值 ai 就是所有连出去的 ais 的 mex。很显然树上每个点的权值都是确定的。

考虑环上任意一个点,注意到它的权值只和它在环上的后继有关。这个点的权值只有两种可能。(后继是非环出度的 mex 或是不是),钦点起点暴力填环上的所有权值最后检验一下就行了。

码起来很烦。

16.CF871E Restore the Tree

感觉不是很难,还是传统构造,但我为啥总是想偏啊……

设所有的关键点为 p1,p2,...,pm。以 p1 为根节点,可以确定所有点的深度。

考虑 pi(i2) 到根节点 p1 路径上的所有点 x ,一定满足 dis(p1,x)+dis(pi,x)=dep(pi) 。这样由所有关键点组成的虚树就能确定了。

考虑剩下的点,要挂在虚树上的哪个点上?因为 dep(x)+dep(y)=dis(x,y)+2dep(lcax,y) ,所以能确定任意点和关键点的 lca 。枚举每个非关键点,计算它和所有关键点的 lca 中最深的一个,就挂在这个点上。

使用 vector 维护挂在每个点上的点集,很显然只有它们的深度是从 1 开始的一段连续段时才是合法的。

17.P3830 [SHOI2012]随机树

神仙题。也可能是我期望太菜了。

第一问中,每次操作相当于随机抽出一个点把它分裂成两个点,深度 +1。设第 i1 次扩展完的结果是 fi。(此时应有 i 个叶节点)则显然 fi=(i1)fi1+fi+2i

第二问非常巧妙。设 fi,j 表示一个子树有 i 个叶节点,深度为 j 的概率。转移时枚举左儿子有 k 个叶节点,转移为 fi,j=i=1k1(1(1fk,j1)(1fik,j1))i1,分子有点像个卷积的形式。

分母是怎么来的呢?考虑一个有 n 个叶节点的子树,它左子树有 k 个叶节点的概率都是 1n1,是不随 k 而变化的。不加任何限制,把一个子树分裂成 n 个叶节点的方案数是 (n1)!。考虑分裂出 n 个叶节点,其中 k 个在左子树的方案数,要分裂 n1 次,先分裂根节点才能达到左右子树都出现。还剩下 n2 次可以选择是在左子树还是右子树里面分裂。左子树分裂出 k 个叶子的方案数是 (k1)!,同理右子树的是 (nk1)!。再考虑分裂左右子树的顺序(类似归并排序的感觉),方案数再乘上 (n2)!(k1)!(nk1)!,最后的方案数是 (n2)!,是一个非常神奇的定值。

18.CF1572B Xor of 3

nb 构造。不知道出题人是咋想到的。

很显然合法序列所有数的异或和必须为 0

n 是奇数时,依次在 1,3,5,...,n2 几个位置操作。每次操作完第 i 个位置时一定能保证第 i+2 个位置上的数是前缀异或和。因此这样一轮下来 n 号位上的数一定是 1。且对于其它数均有 a2k=a2k1

再依次在 n2,n4,...,3,1 这些位置上操作,就可以把序列变成 0

对于 n 是偶数的情况,拆成两个异或和为 0 且长度为奇数的序列做。

19.CF884F Anti-Palindromize

沉迷炼金工房无法自拔,连着炼了两周做了 0 题,真的太力。😅

前一段时间瞟到这题要 wll,然后我跟着 greedy 的思路想到一半了,接着强拼了个 wll 上去,,,然后当然是假了啦!

有一个广为人知的结论:对于一个长度为 n 的排列,如果每一种颜色的出现次数都 12n 的话,则它以定可以错排成为一个每一位上与原位都不相同的排列。

定义 ini+1 位上的两个数互为一对。很显然我们可以将所有颜色相同的对提取出来,设这种 pair 一共有 m 对,其中最多的颜色出现对数 为 x

如果 2xm ,则我们抽出这 m 对里面每一对费用更小的那一个随意排列即可。

剩下, 2x>m,我们至少需要再抽出 2xm 个颜色与原不同的点。很显然如果新点出自一对,那它们都会被换成 x 的那种颜色。如果那个对里边有一个与那 x 个颜色相同,则在交换过程中一定会造成一个相等的对。我们把所有其它没有含 x 同色的对拎出来挑费用最小的。

posted @   SS80194  阅读(122)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示
主题色彩