回文树写法
#include<cstring>
#include<iostream>
#include<cstdio>
#define LL long long
#define maxn 500021
using namespace std;
int n,len[maxn],fail[maxn],ch[maxn][26];
int N,cnt[maxn],s[maxn],last,p;
char ss[maxn];
LL ans;
int get(int x){
while((s[n]==s[n-len[x]-1]||s[n-len[x]-1]==-1)&&x!=1)x=fail[x];
return x;
}
void insert(int c){
s[++n]=c;
int cur=get(last);
if(cur==1){
last=0;
return;
}
if(!ch[cur][c]){
fail[p]=ch[get(fail[cur])][c];
len[p]=len[cur]+2;
ch[cur][c]=p++;
}
last=ch[cur][c];
cnt[last]++;
}
int main(){
scanf("%d%s",&N,ss);
p=2,s[0]=-1,fail[0]=1,len[1]=-1;
for(int i=0;i<N;i++)insert(ss[i]-'0');
for(int i=p-1;i>0;i--)cnt[fail[i]]+=cnt[i];
for(int i=2;i<p;i++)
if(~len[i]&1)ans+=cnt[i];
printf("%lld",ans);
return 0;
}