题解:
后缀数组求出height
然后ans=所有串-所有height
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=;
int t,ans,n,m,wa[N],wb[N],wsf[N],wv[N],sa[N],rank[N],height[N],s[N],a[N];
char str[N],str1[N],str2[N];
int cmp(int *r,int a,int b,int k)
{
return r[a]==r[b]&&r[a+k]==r[b+k];
}
void getsa(int *r,int *sa,int n,int m)
{
int *x=wa,*y=wb;
for (int i=;i<m;i++)wsf[i]=;
for (int i=;i<n;i++)wsf[x[i]=r[i]]++;
for (int i=;i<m;i++)wsf[i]+=wsf[i-];
for (int i=n-;i>=;i--)sa[--wsf[x[i]]]=i;
for (int p=,j=;p<n;j*=,m=p)
{
p=;
for (int i=n-j;i<n;i++)y[p++]=i;
for (int i=;i<n;i++)
if (sa[i]>=j)y[p++]=sa[i]-j;
for (int i=;i<n;i++)wv[i]=x[y[i]];
for (int i=;i<m;i++)wsf[i]=;
for (int i=;i<n;i++)wsf[wv[i]]++;
for (int i=;i<m;i++)wsf[i]+=wsf[i-];
for (int i=n-;i>=;i--)sa[--wsf[wv[i]]]=y[i];
swap(x,y);x[sa[]]=;p=;
for (int i=;i<n;i++)x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
}
void getheight(int *r,int n)
{
int j,k=;
for (int i=;i<=n;i++)rank[sa[i]]=i;
for (int i=;i<n;i++)
{
if (k)k--;
else k=;
j=sa[rank[i]-];
while (r[i+k]==r[j+k])k++;
height[rank[i]]=k;
}
}
int main()
{
scanf("%d",&t);
while (t--)
{
scanf("%s",str);
int len=strlen(str);
for (int i=;i<len;i++)s[i]=str[i];
s[len]=;
getsa(s,sa,len+,);
getheight(s,len);
int ans=(+len)*len/;
for (int i=;i<=len;i++)ans-=height[i];
printf("%d\n",ans);
}
}