P3649 [APIO2014]回文串

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 }

 

posted @ 2019-10-26 13:45  麻辣猪仔  阅读(106)  评论(0编辑  收藏  举报