模拟47 题解
A. Emotional Flutter
显然第一步的位置只有k种不同的取值。
前缀和对步长k取模,那么每条黑线限制的是一段连续区间。
问题是是否完全限制k个位置。
第一个思路是动态开点线段树,想了想,害怕卡空间,没打。
之后的想法是将每条线段离线下来,对线段的左右端点和两条线段之间的区域离散化,
直接用差分数组表示覆盖次数,如果存在覆盖为0的位置则有解。
更好的思路是直接贪心求解。
将所有线段按左端点排序,不断对右端点取max,如果右端点的max小于当前左端点,那么存在解。
B. Endless Fantasy
询问子树的众数,直接线段树合并就完了。
C. 字符消除2
本题可以简化为:
给定字符串s,求一个字典序最小的01串使得该01串的循环节个数及长度与原串相同。
如果对字符串做kmp,那么不断对n翻next,即可取得所有的循环节。
只要保证01串的n的每一个next都与原字符串相同即可。
将翻到的next放在一个数组里。
考虑从小到大处理每个可能的next,分类讨论两种情况:
1.该next小于等于前一个next乘2。
那么显然要将前一个next的后缀接在后面,保证该next的next恰为前一个next。
2.该next大于前一个next乘2。
比较好的性质是该情况不会出现超过logn次,考虑等比数列的性质,对这些next求和只有n级别。
还是将前一个next所表示的字符串接在最后,以保证该next的next可以为前一个next。
对于中间空出来的部分:
暴力不断向前翻next,如果可能存在不合法的情况,为保证字典序最小,将中间的最后一个位置设为1。