题目1 BZOJ 3676 APIO2014 回文串
算法讨论:
cnt表示回文自动机上每个结点回文串出现的次数。这是回文自动机的定义考查题。
1 #include <cstdlib> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 7 using namespace std; 8 9 const int C = 26; 10 const int N = 300000 + 5; 11 typedef long long ll; 12 13 char str[N]; 14 int len; 15 ll ans; 16 17 struct State { 18 int len, num, cnt, s, fail, next[C]; 19 }st[N]; 20 21 struct PTree { 22 int n, sz, last; 23 24 int newnode(int len) { 25 st[sz].len = len; 26 return sz ++; 27 } 28 29 void Init() { 30 n = sz = last = 0; 31 newnode(0); newnode(-1); 32 st[n].s = -1; 33 st[0].fail = 1; 34 } 35 36 int getfail(int x) { 37 while(st[n - st[x].len - 1].s != st[n].s) x = st[x].fail; 38 return x; 39 } 40 41 void count() { 42 for(int i = sz - 1; i >= 0; -- i) 43 st[st[i].fail].cnt += st[i].cnt; 44 } 45 46 void add(int c) { 47 st[++ n].s = c; 48 int cur = getfail(last); 49 if(!st[cur].next[c]) { 50 int now = newnode(st[cur].len + 2); 51 st[now].fail = st[getfail(st[cur].fail)].next[c]; 52 st[cur].next[c] = now; 53 st[now].num = st[st[now].fail].num + 1; 54 } 55 last = st[cur].next[c]; 56 st[last].cnt ++; 57 } 58 }ptree; 59 60 int main() { 61 scanf("%s", str); 62 len = strlen(str); 63 ptree.Init(); 64 for(int i = 0; i < len; ++ i) 65 ptree.add(str[i] - 'a'); 66 ptree.count(); 67 for(int i = 0; i < ptree.sz; ++ i) { 68 ans = max(ans, 1LL * st[i].cnt * st[i].len); 69 } 70 printf("%lld\n", ans); 71 return 0; 72 }