The meaning of problems
N to string two two splicing, asked after stitching \ (n \ times n \) string in the number of palindrome string.
analysis
All positive string into the dictionary tree, horse-drawn carriage which ran all the strings prefix and suffix string is a palindrome, recording position, playing with a query to the dictionary tree, makes up two string palindrome string in three ways:
End not match, playing a suffix string is palindromic.
Matching the end, it is the suffix string is a palindrome string.
Matching end, the string is equal to n-playing.
Dictionary tree maintenance of the current position and the number of positive string current position with a positive number suffix string palindrome string.
Code
#include<cstring>
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<map>
#define fi first
#define se second
#define pb push_back
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=2e6+10;
int p[maxn*2],f[2][maxn],len[maxn],sum[2][maxn];
char s[maxn],t[maxn*2];
int son[maxn][26],tot;
ll ans;
void ins(int dl,int dr){
int rt=0;
for(int i=dl;i<=dr;i++){
if(f[1][i]) sum[1][rt]++;
if(!son[rt][s[i]-'a']) son[rt][s[i]-'a']=++tot;
rt=son[rt][s[i]-'a'];
if(i==dr) sum[0][rt]++;
}
}
void qy(int dl,int dr){
int rt=0;
for(int i=dr;i>=dl;i--){
if(f[0][i]) ans+=sum[0][rt];
if(!son[rt][s[i]-'a']) return;
rt=son[rt][s[i]-'a'];
if(i==dl) ans+=sum[1][rt]+sum[0][rt];
}
}
int mlc(int dl,int dr){
int m=0,p0=1;p[1]=1;t[++m]='#';
for(int i=dl;i<=dr;i++){
t[++m]=s[i];
t[++m]='#';
}
for(int i=2;i<=m;i++){
int j=min(p[p0]+p0-i,p[2*p0-i]);
if(i+j<p[p0]+p0){
p[i]=j;
}else{
while(i-j>=1&&i+j<=m&&t[i-j]==t[i+j]) ++j;
p[i]=j;p0=i;
}
}
for(int i=dl;i<dr;i++){
if(p[i-dl+2]-1==i-dl+1) f[0][i]=1;
if(p[dr-2*dl+i+3]-1==dr-i) f[1][i+1]=1;
}
}
int main(){
//ios::sync_with_stdio(false);
//freopen("in","r",stdin);
int n;
scanf("%d",&n);int l=1;
for(int i=1,m;i<=n;i++){
scanf("%d%s",&len[i],s+l);
mlc(l,l+len[i]-1);
ins(l,l+len[i]-1);
l+=len[i];
}l=1;
for(int i=1;i<=n;i++){
qy(l,l+len[i]-1);
l+=len[i];
}
cout<<ans<<'\n';
return 0;
}