P3649 [APIO2014]回文串
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 300010; 5 char s[maxn]; 6 int n; 7 struct PAM { 8 int last; 9 struct Node { 10 int cnt, len, fail, son[27]; // cnt为以i为结尾的回文子串个数,len为长度 11 Node(int len, int fail) : len(len), fail(fail), cnt(0){ 12 memset(son, 0, sizeof(son)); 13 }; 14 }; 15 vector<Node> st; 16 inline int newnode(int len, int fail = 0) { 17 st.emplace_back(len, fail); 18 return st.size()-1; 19 } 20 inline int getfail(int x, int n) { 21 while (s[n-st[x].len-1] != s[n]) x = st[x].fail; 22 return x; 23 } 24 inline void extend(int c, int i) { 25 int cur = getfail(last, i); 26 if (!st[cur].son[c]) { 27 int nw = newnode(st[cur].len+2, st[getfail(st[cur].fail, i)].son[c]); 28 st[cur].son[c] = nw; 29 } 30 st[ last=st[cur].son[c] ].cnt++; 31 } 32 void init() { 33 scanf("%s", s+1); 34 n = strlen(s+1); 35 s[0] = 0; 36 newnode(0, 1), newnode(-1); 37 last = 0; 38 for (int i = 1; i <= n; i++) 39 extend(s[i]-'a', i); 40 } 41 ll count() { 42 // 本质相同的字符串 43 for (int i = st.size()-1; i >= 0; i--) 44 st[st[i].fail].cnt += st[i].cnt; 45 46 ll ans = 0; 47 /* 48 for (int i = 2; i <= st.size()-1; i++) 49 ans += st[i].cnt, cout << st[i].cnt << " " << st[i].len << endl; 50 */ 51 for (int i = 2; i <= st.size()-1; i++) 52 ans = max(ans,(ll)st[i].cnt*st[i].len); 53 return ans; 54 } 55 }pam; 56 int main() { 57 pam.init(); 58 printf("%lld\n",pam.count()); 59 return 0; 60 }