📚【模板】回文树

#include <stdio.h>
#include <string.h>
#include <bits/stl_algobase.h>
const int N = 524288;
struct PAM {
	int cid[26];
	int size, len;
	int fail;
	int cnt;
} pam[N];
#define sid(id,choice) pam[id].cid[choice]
#define size(id) pam[id].size
#define fail(id) pam[id].fail
#define len(id) pam[id].len
#define cnt(id) pam[id].cnt
int pam_tot, n;
char pattern[N];
int get(int x,int y) {
	while(pattern[y] != pattern[y-len(x)-1]) 
		x = fail(x);
	return x;
}
void pam_work() {
	n = strlen(pattern+1);
	++pam_tot;
	len(1) = -1;
	fail(0) = 1;
	pattern[0] = -1;
	for(int i = 1, pass = 0;i <= n;++i) {
		int sc = pattern[i]-'a';
		int id = get(pass,i);
		if(!sid(id,sc)) {
			++pam_tot;
			fail(pam_tot) = sid(get(fail(id),i),sc);
			len(pam_tot) = len(id)+2;
			sid(id,sc) = pam_tot;
			size(pam_tot) = size(fail(pam_tot))+1;
		}
		pass = sid(id,sc);
		++cnt(pass);
		//size : 以该字符为结尾的回文串个数;
		//len : 以该字符为结尾的最长回文串长度;
		//fail : 指向以该字符为结尾的最长回文串的最长回文子串;
		printf("%d %d %d %d\n",pass,size(pass),len(pass),fail(pass));
	}
}
int query_tot() {
	//pam_tot-1 即为本质不同回文串长度;
	return pam_tot-1;
}
long long query_longest() {
	long long res = 0;
	for(int i = pam_tot;~i;--i) {
		cnt(fail(i)) += cnt(i);
	}
	for(int i = 1;i <= pam_tot;++i) 
		res = std :: max(res,(long long)cnt(i)*len(i));
	return res;
}
signed main() {
	scanf("%s",pattern+1);
	pam_work();
	printf("%d\n",query_tot());
	printf("%lld",query_longest());
}
posted @ 2022-07-30 07:20  bikuhiku  阅读(22)  评论(0编辑  收藏  举报