算法模板整理和代码片段
Manacher
点击查看代码
int Manacher(string s) {
string t = "!#";
for (char i : s) t += i, t += '#';
t += '?';
vector<int> d(t.size() + 5, 0);
for (int i = 1, p = 0, r = 0; i < t.size(); i++) {
if (r >= i) d[i] = min(d[p * 2 - i], r - i);
while (t[i - d[i]] == t[i + d[i]]) d[i]++;
if (i + d[i] - 1 > r) r = i + d[i] - 1, p = i;
}
return *max_element(d.begin(), d.end()) - 1;
}
前缀函数
点击查看代码(下标从 0 开始)
auto Pi(string s) {
vector<int> pi(s.size() + 1, 0);
for (int i = 1, j = 0; i < s.size(); i++) {
while (j && s[i] != s[j]) j = pi[j - 1];
if (s[i] == s[j]) j++; pi[i] = j;
}
return pi;
}
点击查看代码(下标从 1 开始)
auto Pi(string s) {
vector<int> pi(s.size() + 1, 0);
for (int i = 2, j = 0; i < s.size(); i++) {
while (j && s[i] != s[j + 1]) j = pi[j];
if (s[i] == s[j + 1]) j++; pi[i] = j;
}
return pi;
}
注意代码里的 \(j\) 实际上只是匹配的长度!
Dirichlet 前缀和
点击查看代码
F(i, 2, n) {
if (!v[i]) {
for (int j = 1; j * i <= n; j++)
v[i * j] = 1, a[i * j] += a[j];
}
}
对于每一个数字,乘上一个新的质数就能得到一个新的数字,也就是把每个质数看作是一个维度。

浙公网安备 33010602011771号