回文树
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;