回文树

class pal {
public:
    int next[maxn][26];
    int fail[maxn];
    char str[maxn];
    int len[maxn];
    int last;
    int tot;
    int n;
    
    // 记录节点长度,同时返回一个节点 
    inline int node(int _len) {
        len[tot] = _len;
        return tot++;
    }
    
    // odd根初始化为: 长度为-1  even根初始化len为0
    // 同时str[0]设置为字符集没有的字符 用于判断.
    // even根的fail指针是odd根 odd根的fail指针是自身. 
    void init() {
        last = tot = n = 0;
        node(0); node(-1);
        str[0] = -1;  fail[0] = fail[1] = 1; 
    }
    
    // 获得添加字符后,可以组成回文串的位置. 
    inline int GetFail(int cur) {
        while (str[n-len[cur]-1] != str[n])
            cur = fail[cur];
        return cur;
    }
    
    // 添加新字符  
    void insert(char ch) {
        str[++n] = ch;  
        int cur = GetFail(last), now;
        if (!next[cur][ch]) {
            now = node(len[cur] + 2);
            fail[now] = next[GetFail(fail[cur])][ch]; //和下一句的顺序不能反 
            next[cur][ch] = now;
        }
        last = next[cur][ch];
        // 统计信息. 例如个数之类的.  cnt 
    }
    
    long long getans() {
        // 统计答案    
    }
}pal;
原文地址:https://www.cnblogs.com/cgjh/p/9597562.html