记录编号 |
479631 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[SPOJ 705] 不同的子串 |
最终得分 |
100 |
用户昵称 |
Shirry |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.066 s |
提交时间 |
2017-12-22 13:26:52 |
内存使用 |
20.32 MiB |
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000010;
char s[maxn];
int n,x[maxn],y[maxn],c[maxn],sa[maxn],height[maxn];
void get_sa(){
int *rnk=x,*tp=y;
n=strlen(s+1);
int m=300;
for(int i=1;i<=n;i++)tp[i]=s[i],rnk[i]=s[i];
for(int i=1;i<=m;i++)c[i]=0;
for(int i=1;i<=n;i++)c[tp[i]]++;
for(int i=1;i<=m;i++)c[i]+=c[i-1];
for(int i=n;i>=1;i--)sa[c[tp[i]]--]=i;
for(int j=1;j<=n;j<<=1){
int p=0;
for(int i=n-j+1;i<=n;i++)tp[++p]=i;
for(int i=1;i<=n;i++)if(sa[i]>j)tp[++p]=sa[i]-j;
for(int i=0;i<=m;i++)c[i]=0;
for(int i=1;i<=n;i++)c[rnk[tp[i]]]++;
for(int i=1;i<=m;i++)c[i]+=c[i-1];
for(int i=n;i>=1;i--)sa[c[rnk[tp[i]]]--]=tp[i];
swap(rnk,tp);
rnk[sa[1]]=1;
p=1;
for(int i=2;i<=n;i++){
int O1=sa[i]+j>n?-1:tp[sa[i]+j];
int O2=sa[i-1]+j>n?-1:tp[sa[i-1]+j];
rnk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&O1==O2)?p:++p;
}
m=p;
if(m>=n)break;
}
}
void get_height(){
int k=0,j;
for(int i=1;i<=n;i++)x[sa[i]]=i;
for(int i=1;i<=n;i++){
if(k)k--;
j=sa[x[i]-1];
while(s[i+k]==s[j+k])k++;
height[x[i]]=k;
}
}
int main(){
freopen("subst1.in","r",stdin);
freopen("subst1.out","w",stdout);
scanf("%s",s+1);
get_sa();
get_height();
long long ans=0;
for(int i=1;i<=n;i++)ans+=(long long)(n-sa[i]+1-height[x[i]]);
printf("%lld\n",ans);
return 0;
}