• 洛谷P5496 回文自动机【PAM】模板


    回文自动机模板

    1.一个串的本质不同的回文串数量是(O(n))级别的

    2.回文自动机的状态数不超过串长,且状态数等于本质不同的回文串数量,除了奇偶两个根节点

    3.如何统计所有回文串的数量,类似后缀自动机,不需要重新拓扑排序,因为是按节点顺序插入的,所以逆序上传即可

    建树的时候(0)节点为偶数长度回文的根
    (1)节点为奇数长度回文的根

    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 5e5+7;
    class PAM{
    private:
        int tot,sz[MAXN],len[MAXN],ch[MAXN][26],fail[MAXN],n,last;
        char s[MAXN];
    public:
        void init(){
            scanf("%s",s+1);
            n = strlen(s+1);
            //0和1分别代表偶数长度回文串的根和奇数长度回文串的根
            len[0] = 0; len[1] = -1;
            fail[0] = 1; fail[1] = 0;
            tot = 1; last = 0;
        }
        int getfail(int x, int pos){
            while(s[pos]!=s[pos-len[x]-1]) x = fail[x];
            return x;
        }
        void insert(int x, int pos){
            int u = getfail(x,pos);
            int c = s[pos] - 'a';
            if(!ch[u][c]){
                len[++tot] = len[u] + 2;
                fail[tot] = ch[getfail(fail[u],pos)][c];
                sz[tot] = sz[fail[tot]] + 1;
                ch[u][c] = tot;
            }
            last = ch[u][c];
        }
        void build(){
            int k = 0;
            for(int i = 1; i <= n; i++){
                s[i] = (s[i]-97+k)%26+97;
                insert(last,i);
                printf("%d ",k = sz[last]);
            }
        }
    }pam;
    int main(){
        pam.init();
        pam.build();
        return 0;
    }
    
    
  • 相关阅读:
    IO模型
    Redis的cluster模式
    #4789. 啊孤独感放辣椒
    #4754. 旅途
    #3189. 八纵八横(c)
    洛谷P2624 [HNOI2008]明明的烦恼
    CF938G Shortest Path Queries
    [CTSC2010]珠宝商
    洛谷P1903 [国家集训队]数颜色 / 维护队列
    AtCoder3611 Tree MST
  • 原文地址:https://www.cnblogs.com/kikokiko/p/12826514.html
Copyright © 2020-2023  润新知