11.3 QOJ6482, LG P15925
QOJ6482. Popcount Words
套路题,主要是看你有没有做过 popcount 序列性质相关的题目。
由于文本串过长,没法做 kmp,考虑用文本串匹配模式串。
先将所有询问串离线,插入到 trie 中建 AC 自动机。popcount 序列有一定的规律可循,一般会采用其倍增结构:
\(s_{2i} = s_i\),\(s_{2i+1} = 1 - s_i\)。
不难观察到,设串 \(F_{k, 0}\) 表示 \(s[0, 2^{k})\),\(F_{k, 1}\) 表示 \(s[2^{k}, 2^{k+1})\),任意 \(w(l, r)\) 都可以拆分为 \(O(\log V)\) 个 \(F_{k, o}\)。
拆分考虑两个部分 \(l \to 2^h \to r\):\(l \to 2^h\),每次找到 \(2^k= \mathrm{lowbit}(l)\),拼上串 \(F_{k, \mathrm{popc}(l) \& 1}\),\(l \gets l + 2^k\)。到 \(l = 2^{\lfloor\log r\rfloor}\) 后,倒着枚举 \(k\),每次找到 \(2^k = \mathrm{highbit}(r)\),拼上串 \(F_{k, \mathrm{popc}(l)\&1}\),\(l \gets l + 2^k\)。两个部分除了枚举顺序其余完全一致。考虑若 \(l, r\) 在同一层,即 \(\lfloor \log x\rfloor\) 相同时,我们需要加入一些小判断,例如 \(l + 2^k\) 是否 \(\le r\)。
相当于对于由若干个 \(F_{k, o}\) 拼接得到的串做 AC 自动机上的匹配,考虑定义 \(f_{u, k, o}\) 表示从 AC 自动机上的状态 \(u\) 出发,跑一个 \(F_{k, o}\) 串的匹配最后到达的状态(有点像倍增是不是)。由 \(F_{k, o} = F_{k-1, o} + F_{k - 1, o \oplus 1}\) 得知:
预处理出 \(f_{u, k, o}\),复杂度为 \(\mathcal O(S \log V)\)。
但是我们要求的问题是,每个状态被匹配过多少次。定义 \(g_{u, k, o}\) 表示从状态 \(u\) 出发后面接 \(F_{k, o}\) 的次数,类似于后缀和,按层 \(k\) 往下传递信息,直到 \(k = 0\):
记 \(h_u\) 表示状态 \(u\) 被匹配到的次数,则:
最后做一遍 fail 树上答案合并。
总的复杂度 \(\mathcal O(S \log V + n \log V)\)。
[TOPC 2023] Introversion
这种无聊题就别评紫了吧,首先相邻不相同的反面是简单的,你只需要把两个绑在一起就行。
考虑容斥,坏事件为相邻且相同的一对,设钦定有 \(i\) 个相同相邻的方案数为 \(g_i\),则答案为 \(\sum (-1)^ig_i\)。
考虑到,原序列中有一些位置已经固定了,且保证相同不相邻,所以有 \(3\) 类情况,我们只需要考虑 \(2\) 类:
- 在序列中没出现过。
- 在序列中出现过恰好一次。
定义 \(f_{i, j, k}\) 表示前 \(i\) 个数已经固定,钦定了第一类 \(j\) 个相邻且相同的对,第二类 \(k\) 个相邻且相同的对。设第一类总共有 \(c_1\) 个,第二类总共有 \(c_2\) 个。
第二种转移成立当且仅当 \(a_{i-1},a_i\) 均为 \(0\),第三种转移成立当且仅当 \(a_{i-1}\) 和 \(a_i\) 之一为第二类,另一个为 \(0\)。
剩下的数总共是 \(c_2 - k + 2(c_1 - j)\) 个,任意排列即可,所以 \(g_{j + k} \gets (c_2-k+2(c_1-j))!f_{n, j, k}\)。但要注意的是,相同的数不区分,所以还应带上一个修正系数 \(2^{-(c_1-j)}\)。

浙公网安备 33010602011771号