P3649 [APIO2014]回文串
标签:lld void std eof api max 个数 scan init
P3649 [APIO2014]回文串
1 #include 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 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 )
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 49 ans += st[i].cnt, cout 50 */
51 for (int i = 2; i 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 }
P3649 [APIO2014]回文串
标签:lld void std eof api max 个数 scan init
原文地址:https://www.cnblogs.com/wstong/p/11742931.html
评论