回文自动机

来源:互联网 发布:数据库系统的主要特点 编辑:程序博客网 时间:2024/05/18 06:32
#include<iostream>#include<cstdio>#include<algorithm>#include<string.h>using namespace std;struct treee{int fa, son[27];long long cnt, len;};treee tree[300005];int tot = 2;int last;char str[300005];void init(){tree[0].fa = 1; tree[0].len = 0;tree[1].fa = 1; last = 0; tree[1].len = -1;}int getfail(int num, int pos){while (str[pos - 1 - tree[num].len] != str[pos]){num = tree[num].fa;}return num;}void insert(int pos){int fa = getfail(last, pos);int value = str[pos] - 'a';int now = tree[fa].son[value];if (tree[fa].son[value] == 0){ now = tot++; tree[now].len = tree[fa].len + 2;tree[now].fa = tree[getfail(tree[fa].fa, pos)].son[value];//更具对称性这里是不阔能为0的,后缀链接指向的是前面出现过的最长回文串且这个回文串是这个串的后缀tree[fa].son[value] = now;                              //如abbacabb 现在你加一个a 是abbacabba 是个回文串 bbacabb的后缀链接指向 bb 那么b后面会有a么,显然是有的,因为abba是}                                                           //abbacabba的最长回文后缀,那么更具对称性前面一定还有一个abba 所以bb后面一定有atree[now].cnt++;                                            //然后如果找串的话就是1.从0点开始的就依次经过然后每个字母都二倍2.从1开始的除了第一个不二倍其他都二倍last = now;}int main(){char c; int i = 1;str[0] = '*';while ((c = getchar())!= '\n'){if (c<'a' || c>'z')continue;str[i] = c; i++;}//cout << str << endl;int lenth = i - 1;init();for (int i = 1; i <=lenth; i++){insert(i);}long long ans = -1000000000; long long temp = 0;for (int i = tot - 1; i >= 2; i--){temp = tree[i].cnt*tree[i].len;ans = max(ans, temp); tree[tree[i].fa].cnt += tree[i].cnt;}printf("%lld\n", ans);}

原创粉丝点击