P3649 [APIO2014]回文串
2021-07-12 06:04
标签:img -- div struct lin ima res 针对 code ps:针对 fail 链出的题,一个点的fail指向的节点一定是这个点的子串。 P3649 [APIO2014]回文串 标签:img -- div struct lin ima res 针对 code 原文地址:https://www.cnblogs.com/zgglj-com/p/9610193.htmlconst int N = 300005;
inline void upd(LL &a, LL b) {
(a b);
}
struct data {
int len, fail;
int ch[26];
};
struct PldTree {
int res[N];
int tot, last;
char s[N];
data node[N];
void Inite() {
mem(res, 0);
tot = last = 1;
node[1].len = -1;
node[0].fail = 1;
}
void Insert(int i) {
while(s[i] != s[i - node[last].len - 1]) last = node[last].fail;
if (!node[last].ch[s[i] - ‘a‘]) {
node[++tot].len = node[last].len + 2;
int tp = node[last].fail;
while(s[i] != s[i - node[tp].len - 1]) tp = node[tp].fail;
node[tot].fail = node[tp].ch[s[i] - ‘a‘];
node[last].ch[s[i] - ‘a‘] = tot;
}
last = node[last].ch[s[i] - ‘a‘];
res[last]++;
}
LL get() {
LL ans = 0;
for (int i = tot; i > 1; --i) {
res[node[i].fail] += res[i];
upd(ans, 1ll * res[i] * node[i].len);
}
return ans;
}
};
PldTree T;
int main()
{
T.Inite();
scanf("%s", T.s + 1);
int n = strlen(T.s + 1);
Rep(i, 1, n) T.Insert(i);
pr(T.get());
return 0;
}