比赛的时候没能静下心来看看回文树
今天发现当时静下心来学学两三个小时肯定能做出来....
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 300010+100;
typedef long long ll;
int i,nn;
ll ans;
char s[maxn];
typedef long long ll;
ll res[maxn];
struct Palindrome_Automaton{
int ch[maxn][26];
int all[maxn];
int i,len[maxn],next[maxn][26],fail[maxn],cnt[maxn],last,cur,S[maxn],p,n;
int newnode(int l ,int cur){
if(cur==-1){
for(int i = 0;i<26;++i){
next[p][i] = 0;
ch[p][i] = 0;
}
all[p] = 0;
cnt[p] = 0;
len[p] = l;
return p++;
}
for(int i = 0;i<26;++i){
next[p][i] = 0;
ch[p][i] = ch[cur][i];
}
all[p] = all[cur];
cnt[p] = 0;
len[p] = l;
return p++;
}
void init(){
p = n = last = 0;
newnode(0,-1);
newnode(-1,-1);
S[0] = -1;
fail[0] = 1;
}
int get_fail(int x){
while(S[n-len[x]-1]!=S[n])x = fail[x];
return x;
}
void add(int c){
c-='a';
S[++n] = c;
int cur = get_fail(last);
if(!next[cur][c]){
int now = newnode(len[cur]+2,cur);
if(!ch[now][c]){
ch[now][c] = 1;
all[now] = all[now]+1;
}
fail[now] = next[get_fail(fail[cur])][c];
next[cur][c] = now;
}
last = next[cur][c];
cnt[last]++;
}
void count(){
for(int i = p-1;i>=0;--i){
res[fail[i]]+=(ll)all[i]*cnt[i]+res[i];
cnt[fail[i]]+=cnt[i];
}
}
}q;
int main(){
scanf("%s",s);
int len = strlen(s);
q.init();
for(int i = 0;i<len;++i){
q.add(s[i]);
}
q.count();
cout<<res[0]<<endl;
}