字符串选做
认真学术
CF985F
尝试提取有用信息。
我的思路是记录每一个字符以前最后的字符的下标,设为 \(val\),具体来说对于区间内所有字符 \(val \gets val - l + 1\),并且第一次出现的字符将 \(val_pos \gets -1\)。
显然动态哈希是可以这样做的,不过非常麻烦。
由于实际字符不重要,可以把每种字符的存在序列哈希,提取出来排遍序直接判就行了,代码好写很多。
AT_arc172_c
考虑挪动第一个。
对称性,如果 \(c_1 = B\) 那么整体反转。
做一遍前缀和,A 设为 \(-1\),B 设为 \(1\)。
发现把第一个在 \(i - 1\) 时挪到在第 \(i\) 个是把前缀和数组 \(p_{i - 1} \gets p_i + 1\),其他不变。
由于是顺序挪过去的,\(p_{i - 1}\) 就是最初值。
所以当且仅当\(p_{i - 1}\),\(p_i + 1\) 正负性不一致时贡献答案,并且由于改的下标不一样不会算重。
https://yundouxueyuan.com/p/YDRG013A
没找到原题
考虑两个字符串的排序,暴力方法是一遍扫过去判第一个不同的,发现这个有单调性,所以可以二分。
那么多个字符串也可以这样搞,string 自带的比较是 \(O(L)\)的,把 check 算法扔进 sort 里面就可以优化。sort 还能优化,挺神奇的。
这里要求相同元素保持顺序,可以比较下标,也可以用 stable_sort,不过 stable_sort 元素相等时 cmp 必须返回 false,不然就是 UB。感觉没直接比较下标好用。
然后临项交换排序,每次交换可以解决一个逆序对,所以总共操作数是排完序后下标产生的逆序对数。算个小结论。
P3435
实际上是求每一个前缀最长的可以拼出该串的前缀,并且前缀的前缀长度应该不小于前缀的一半。
可以发现实际上是求前缀最小 border。前缀的前缀拼出前缀就是相当于一个前缀与后缀相等。如果不小于前缀的一半的前缀的前缀不存在,由于更小的前缀的前缀一定能将自己的重复一遍的作为更长的前缀,所以条件不成立。只有可能是没有 border。
为什么我说话这么绕,不会说人话了。
以后真的能看懂吗 qwq
CF580E
线段树维护哈希,查询有两种方法,一个是哈希出 \([l, l + d - 1]\) 的值然后复制 \(k\) 遍,可以做,不过实现很麻烦,还一个是结论,\([l, r - d] = [l + d, r]\) 是 \([l, r]\) 是 \([l, l + d - 1]\) 重复做组成的充要条件,直接判就行了。
CF455B
可以玩 \(k\) 轮,下一轮先手由这一轮输赢决定,所以可以故意这一轮输让自己下一轮赢,要算可选胜或败,必胜,必败。
观察到前缀,扔 Trie 上去,如果节点有值且没有子节点,那么这个节点必败,然后树形博弈 dp,做出来以后分析一下第 \(k - 1\) 轮和第 \(k\) 轮就行。
CF842D
有二进制运算,转化为二进制,实际上就是原序列异或一个值后查询。扔 01-Trie 上去,如果此位要被异或那就反转两边,如果 0 子树叶子是满的就考虑 1 子树,贪心搜下去就能找到 mex。
P7114
枚举 AB,枚举重复次数,前缀后缀预处理出现奇数次的字符的数量 \(val\),转化为求一个前缀中 \(val\) 小于某个值 \(x\) 的个数,离线下来扫描线维护即可。

浙公网安备 33010602011771号