Meaning of the questions:
Several times a query string for each sub-string of resolved into \ (the AABB \) Total of formula.
Knowledge points:
Suffix array, to reconcile the idea of difference, thinking
solution:
\ (a [], b [ ] \) is the current start and end of each \ (AA \) Number Scheme string, then all \ (b_i \ times a_ {i + 1} \) and is the answer. And because there are so seek to limit the length of good demand, so the idea into key points, from \ (1 \) to \ (\ frac {n} { 2} \) were set up key point is that each \ (len \) position a point, then the adjacent \ (2 \) contributed key points of the answer is seeking a.
In particular, for two adjacent key points \ (I \) and \ (J \) , \ (I \) and \ (J \) respectively forward, backward seek out a common portion (note that the foregoing does not exceed \ (len-1 \) , the back does not exceed \ (len \) , otherwise it will repeat calculate the contribution), if \ (lcs \) and \ (lcp \) and less than \ (len \) , that there is no repeat part affirmed No solution. Otherwise, repeat that part of the left to the far left and at that point the beginning of a period in which the far right is the end of the period. Differential click on it.
Remarks:
Note: 1, must be packaged SA. 2, this question has a lot of details worthy of consideration. 3, this blog Figure clearly enough: https://gypsophila.blog.luogu.org/solution-p1117
Code:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=300010;
ll ans,a[maxn],b[maxn];
int n,T,mlog[maxn];
struct SA
{
char s[maxn];
int m,sa[maxn],rnk[maxn],height[maxn],c[maxn],y[maxn],f[20][maxn];
void clear()
{
m=26;
memset(f,0x3f,sizeof(f));
for (register int i=0;i<=n+5;i++)
sa[i]=rnk[i]=height[i]=y[i]=0;
}
void rsort()
{
int i;
for (i=0;i<=m+1;i++)
c[i]=0;
for (i=1;i<=n;i++)
c[rnk[i]]++;
for (i=2;i<=m;i++)
c[i]+=c[i-1];
for (i=n;i>=1;i--)
sa[c[rnk[y[i]]]--]=y[i],y[i]=0;
}
void getsa()
{
int i,k,p=0;
for (i=1;i<=n;i++)
rnk[i]=s[i]-'a'+1,y[i]=i;
rsort();
for (k=1;k<n&&p<n;k<<=1,m=p)
{
p=0;
for (i=n-k+1;i<=n;i++)
y[++p]=i;
for (i=1;i<=n;i++)
if (sa[i]>k)
y[++p]=sa[i]-k;
rsort();
swap(rnk,y);
rnk[sa[p=1]]=1;
for (i=2;i<=n;i++)
rnk[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k])?p:(++p);
}
}
void getheight()
{
int i,j,k=0;
for (i=1;i<=n;i++)
{
if (rnk[i]==1)
continue;
if (k)
k--;
j=sa[rnk[i]-1];
while (i+k<=n&&j+k<=n&&s[i+k]==s[j+k])
k++;
height[rnk[i]]=k;
}
}
void init()
{
int i,j;
for (i=1;i<=n;i++)
f[0][i]=height[i];
for (j=1;(1<<j)<=n;j++)
for (i=1;i+(1<<j)-1<=n;i++)
f[j][i]=min(f[j-1][i],f[j-1][i+(1<<(j-1))]);
}
int rmq(int l,int r)
{
int k=mlog[r-l+1];
return min(f[k][l],f[k][r-(1<<k)+1]);
}
}A,B;
int LCP(int i,int j)
{
i=A.rnk[i],j=A.rnk[j];
if (i>j)
swap(i,j);
i++;
return A.rmq(i,j);
}
int LCS(int i,int j)
{
i=n+1-i,j=n+1-j;
i=B.rnk[i],j=B.rnk[j];
if (i>j)
swap(i,j);
i++;
return B.rmq(i,j);
}
int main()
{
int i,j,len,lcs,lcp,Len;
scanf("%d",&T);
for (i=2;i<=300000;i++)
mlog[i]=mlog[i>>1]+1;
while (T--)
{
scanf("%s",A.s+1);
n=strlen(A.s+1);
A.clear(),B.clear();
ans=0;
for (i=0;i<=n+1;i++)
a[i]=b[i]=0;
for (i=1;i<=n;i++)
B.s[i]=A.s[n+1-i];
A.getsa();
B.getsa();
A.getheight();
B.getheight();
A.init();
B.init();
for (len=1;len<=(n>>1);len++)
for (i=len,j=i+len;j<=n;i+=len,j+=len)
if (A.s[i]==A.s[j])
{
lcp=min(len,LCP(i,j)),lcs=min(len-1,LCS(i-1,j-1));
if (lcp+lcs>=len)
{
Len=lcs+lcp-len+1;
a[i-lcs]++,a[i-lcs+Len]--;
b[j+lcp-Len]++,b[j+lcp]--;
}
}
for (i=1;i<=n;i++)
a[i]+=a[i-1],b[i]+=b[i-1];
for (i=1;i<=n-1;i++)
ans+=1ll*b[i]*a[i+1];
printf("%lld\n",ans);
}
return 0;
}