算法复健计划——构造题专栏
第一篇博客就献给算法题解了,根据知乎上大佬的说法,可以先做构造题,提升自己的思维水平,我这里也就先从构造题入手,慢慢恢复自己的做题能力。那么就开始吧!
cf round 735D (1554D) 2023/10/14
题目
给定一个正整数n,要求构造字符串,满足如下条件:
- 长度为n;
- 仅包含小写字母;
- 相同子串出现次数为奇数。
数量级:t次询问($1 \leq t \leq 500$),每次的n($3 \leq n \leq 10^5$),n之和不超过$3 \cdot 10^5$。
解法
由于需要设计一个通用的构造算法,那么首先可以猜测,大概率不会将26个小写字母全部用到,所以目前目标为:用较少的字母种数,设计一个通用的生成算法。
其次,可以发现,对一个字符串中某个字母而言,如果它仅出现了一次,那么包含它的所有子串均仅出现了一次。比如aabbcaab中的c,如果一个子串包含c,不论它的左边界和右边界在哪里,这样的子串有且仅有一个。
因此,可以选定一个字母作为分隔符,放在字符串中间,该字母左边的字符串用于满足长度要求,右边的字符串用于满足相同子串出现次数为奇数。
可以先从短的序列入手,用数学归纳法分析:
- 左边长度 $\leq$ 2:随便构造;
- 左边长度 $ = $ 3:如aba,子串a有偶数个,需要用1个a来平衡,所以右边字符串为a可平衡;
- 左边长度 $ = $ 4:如abab,子串a、b、ab有偶数个,右边字符串为ab可平衡;
- 左边长度 $ = $ 5:如ababa,子串b、ab、ba有偶数个,右边字符串为aba可平衡;
- 左边长度 $ = $ 6:如ababab,子串aba、bab、abab有偶数个,右边字符为abab可平衡;
通过观察,可以找到以下规律:设字符串ababab……为S(a或b结尾均可),则字符串ab+S+c+S一定为满足题目要求的字符串。证明如下:
- 不包含c的子串:对于前一个S中任何一个子串,都有在后一个S中与其位置完全对应的子串。所以如果不考虑最初的ab,对每类子串来说,该类子串均有偶数个。当加入最初的ab时,以这里的a或b作为子串左端点,每类子串又各多了一个,此时每类子串均有奇数个。
- 包含c的子串:c是分隔符,因此每类子串有且只有一个。
字符串ab+S+c+S的长度为 $2|S|+3$ 。
最终解法如下:
- n较小($n\leq26$)的时候:直接放n个不同字母;
- n较大的时候:n是奇数,直接用ab+S+c+S的方式构造;n是偶数,字符串最后放一个d,问题退化为n-1的形式,使用奇数方法解决即可。
代码(核心部分)
1 |
|
思考
好久没有写算法题和博客了,下次一定注意~
这道题是div2的D,也是想了得有一二十分钟才会做,之前还走了点岔路。老样子,总结复盘一下:
前期思考
第一眼看到这道题,下意识以为是分治+递归,将字符串从中间劈开,左右两边分别考虑。后面发现不太行,有两点原因:
- 小写字母个数有限,最终两边的字符串不得不用相同的字母时,无法将二者独立考虑;
- 无法独立考虑,可以记录状态。但这里的状态过多,包括每类子串个数的奇偶性,难以完全记录。
总的来说,分治的前提是能将原问题的分拆成多个类似的子问题,同时这些子问题能在一定程度上解耦,这道题很难做到真正的解耦,所以很难通过分治来解决。
换个思考方式,那就是归纳/递推。我在这里是发现分隔符的特性之后,便尝试让左边字符串的重点关注字符串长度,右边字符串的重点满足奇偶性。将长度要求和子串奇偶性要求解耦,发现规律后可以很方便地证明合理性。
代码实现非常简单,没有太多可以说的。标准答案子串S仅用了字母a,构造成a+S+b+S的形式,更加方便。
cf round 629D (1328D) 2023/09/30
题目
题意还是比较简单的,n个动物排成一圈,需要给每个动物染色。要求:相邻的不同动物染成不同的颜色,同种动物没有要求。
问:给出最少所需颜色数量和对应的染色方式。
数量级:动物个数为n($3 \leq n \leq 2 \cdot 10^5$),种数为k($1 \leq k \leq 2 \cdot 10^5$)。
解法
可以从所需颜色数量(记为m)入手考虑,可以发现最多需要三种颜色(每个动物只有两个相邻的动物,如果两个动物颜色不同,中间这只染成第三种颜色就行)。
此时就可以分别讨论满足m=1,m=2,m=3的情况:
m=1:显然,只有一种动物的话,才能这样;
m=2:
2.1:n是偶数:那么1212…12这样染色就行(泛化性更强结论的可以参见图的着色);
2.2:n是奇数,但是有连续的动物是同一种类:如果还是1212这样染,最后一个动物和第一个动物的颜色都会是1,不可以。但连续同种动物给了一些操作空间,可以把任意一对相邻同种动物染成同样颜色,那么最后一个动物就可以是颜色2,不与第一个动重复了;
m=3:也就是n是奇数,且相邻动物种类均不同,那只能多加一个颜色,像1212…123这样构造了。
代码(核心部分)
1 |
|
思考
这道题是div3的D,其实挺简单的,但一开始想的时候还是走错了路,最后看了题解,wa了几次才做对的。这里简单复盘一下:
前期思考
自己一开始想的时候,发现了了可以想象成一个graph然后进行着色。但关键是,没有意识到最多只需要三种颜色,所以打算用dp的思路。
后期发现了这一点,但还是走在dp的道路上一去不复返了。在写状态转移的过程中,发现倒推染色构造方式有些麻烦,觉得dp应该不是正解,所以去看题解了。
代码实现
实现的时候wa了几发,原因如下:
在m=3时,没有多想,觉得12312312…这样的构造方式可以解决所有问题。但是问题就出在第n个动物和第1个动物的关系上,事实上,多一种颜色就是为了解决这个问题,正确的构造方式为1212…123;
代码没有考虑到第1个动物和第n个动物颜色相同,导致满足m=2的情况;
总结
很久没有写题了,思维方面,想出一个div3 D也磕磕绊绊的;相应的,写作方面,第一次写题解,行文逻辑和简约程度都有待优化。但不管怎么说,也算一个开始了,还是要继续努力呀!