题目大意:求
可以被提出来
剩下的就是要求
因为
等价于
单调栈维护即可
代码如下:
#include<algorithm>
#include<cstring>
#include<cstdio>
#define N 500050
using namespace std;
char str[N];
long long ans;
int n,m,top;
int SA[N],las[N],rk[N],buck[N],height[N],l[N],r[N];
inline bool judge(int x,int y,int k){
return las[x]==las[y] && las[x+k]==las[y+k];
}
inline void Radix_Sort(){
for(int i=1;i<=m;i++) buck[i]=0;
for(int i=1;i<=n;i++) buck[rk[las[i]]]++;
for(int i=1;i<=m;i++) buck[i]+=buck[i-1];
for(int i=n;i>=1;i--) SA[buck[rk[las[i]]]--]=las[i];
}
inline void Get_SA(){
n=strlen(str+1);
for(int i=1;i<=n;i++){
las[i]=i;rk[i]=str[i];
}
m=127;Radix_Sort();m=0;
for(int i=1;m<n;i<<=1,top=0){
for(int j=n-i+1;j<=n;j++) las[++top]=j;
for(int j=1;j<=n;j++) if(SA[j]>i) las[++top]=SA[j]-i;
Radix_Sort();m=0;
for(int j=1;j<=n;j++) las[j]=rk[j];
for(int j=1;j<=n;j++) rk[SA[j]]=judge(SA[j],SA[j-1],i)?m:++m;
}
for(int i=1,j=0;i<=n;i++,j=max(j-1,0)){
while(str[i+j]==str[SA[rk[i]-1]+j]) j++;
height[rk[i]]=j;
}
}
struct sta{
int x,id;
}s[N];
int main(){
scanf("%s",str+1);
Get_SA();
top=0;
for(int i=1;i<=n;i++){
while(top && height[i]<s[top].x)
r[s[top--].id]=i;
s[++top].x=height[i];
s[top].id=i;
}
while(top) r[s[top--].id]=n+1;
for(int i=n;i;i--){
while(top && height[i]<=s[top].x)
l[s[top--].id]=i;
s[++top].x=height[i];
s[top].id=i;
}
while(top) r[s[top--].id]=0;
ans=1ll*(n+1)*n*(n-1)/2;
for(int i=1;i<=n;i++) ans=ans-2ll*height[i]*(i-l[i])*(r[i]-i);
printf("%lld",ans);
return 0;
}