3.13——Global Round 26 D
Global Round 26 D
限时每日一题day14。第一次自己做出 2000 分的题目!虽然用了将近两个小时,写法也比官解麻烦很多,但是很开心 ·w·
官解利用了 \(Zfunc\)(或者哈希也可以)来看子串是否匹配,使得对于每种长度 \(O(n)\) 扫一遍字符串可以跳指针,从而将查找优化到调和级数复杂度。但我利用了一个比较特殊的性质——对于非 \(a\) 的某一个特定字符 \(ch\),\(t\) 中包含 \(ch\) 的个数一定是 \(cnt[ch]\) 的约数。因此我的做法是 \(O(n\sqrt n)\) 的。
对于钦定的字符 \(ch\) 数量,可以确定下来 \(s\) 内 \(t\) 的数量,进而 \(t\) 内其他非a字符的数量也得以确定。然后在 \(s\) 内找到最左侧满足所有字符数量的子串,这个子串就是我们构造的 \(t\)。再往后找,直到到达 \(s\) 末尾仍然合法,就说明当前的 \(t\) 是合法的,可以计算答案。
而此时不能将答案天真地加1,因为还需要考虑,构造的 \(t\) 的左右两侧能不能继续加字符 \(a\)。在计算过程中还需要维护 \(3\) 个变量,以备计算这个答案:
\(lenl:\) 左侧开头字符 \(a\) 的数量
\(lenr:\) 右侧结尾字符 \(a\) 的数量
\(len:\) 找到的所有 \(t\) 之间最短的连续子串 \(aa...aa\) 的长度。
根据这三个变量,可以推导一个数学式子来 \(O(1)\) 计算上述答案。这里讲起来比较麻烦,就不过多阐述了。具体细节见代码。