回文自动机模板

 1 #include <bits/stdc++.h>
 2 
 3 const int N = 500010;
 4 
 5 struct Edge {
 6     int nex, v;
 7 }edge[N]; int tp;
 8 
 9 int tr[N][26], fail[N], len[N], tot = 1, last = 1, e[N], Ans, stk[N], top, n;
10 char str[N];
11 
12 inline void add(int x, int y) {
13     edge[++tp].v = y;
14     edge[tp].nex = e[x];
15     e[x] = tp;
16 }
17 
18 inline void init() {
19     len[1] = -1;
20     fail[0] = fail[1] = 1;
21     return;
22 }
23 
24 inline int getpos(int x, int i) {
25     while(str[i] != str[i - len[x] - 1]) {
26         x = fail[x];
27     }
28     return x;
29 }
30 
31 inline void insert(int i, int f) {
32     int x = getpos(last, i);
33     if(!tr[x][f]) {
34         ++tot;
35         fail[tot] = tr[getpos(fail[x], i)][f];
36         len[tot] = len[x] + 2;
37         tr[x][f] = tot;
38     }
39     last = tr[x][f];
40     return;
41 }
42 
43 inline void Insert() {
44     for(int i = 1; i <= n; i++) {
45         insert(i, str[i] - 'a');
46     }
47     return;
48 }
49 
50 void DFS(int x, int p) {
51     if(len[x - 1] >= 2 && (!(len[x - 1] & 1))) {
52         stk[++top] = len[x - 1];
53         while(stk[p] * 2 < stk[top]) {
54             ++p;
55         }
56         if(stk[p] * 2 == stk[top]) {
57             Ans = std::max(stk[top], Ans);
58         }
59     }
60     for(int i = e[x]; i; i = edge[i].nex) {
61         int y = edge[i].v;
62         DFS(y, p);
63     }
64     if(len[x - 1] >= 2 && (!(len[x - 1] & 1))) {
65         top--;
66     }
67     return;
68 }
69 
70 int main() {
71 
72     scanf("%d%s", &n, str + 1);
73     init();
74     Insert();
75 
76     add(2, 1);
77     for(int i = 2; i <= tot; i++) {
78         add(fail[i] + 1, i + 1);
79     }
80 
81     DFS(2, 0);
82     printf("%d\n", Ans);
83     return 0;
84 }
AC代码

以SHOI2011 双倍回文为例。

posted @ 2019-06-10 19:49  huyufeifei  阅读(144)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜