Loading

算法模板整理和代码片段

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];
    }
}

对于每一个数字,乘上一个新的质数就能得到一个新的数字,也就是把每个质数看作是一个维度。

posted @ 2024-06-11 19:29  紊莫  阅读(18)  评论(0)    收藏  举报