SP694 DISUBSTR - Distinct Substrings
题意翻译
给定一个字符串,求该字符串含有的本质不同的子串数量。
题目描述
Given a string, we need to find the total number of its distinct substrings.
输入输出格式
输入格式:
T- number of test cases. T<=20;
Each test case consists of one string, whose length is <= 1000
输出格式:
For each test case output one number saying the number of distinct substrings.
输入输出样例
输入样例#1: 复制
\n 2\n CCCCC\n ABABA
输出样例#1: 复制
\n 5\n 9 Explanation for the testcase with string ABABA: \n len=1 : A,B\n len=2 : AB,BA\n len=3 : ABA,BAB\n len=4 : ABAB,BABA\n len=5 : ABABA\n Thus, total number of distinct substrings is 9.\n
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int N=1e3+5; char s[N]; int n,m,ans; int rnk[N],sa[N],tax[N],tp[N]; inline void Qsort() { for(int i=1;i<=m;++i) tax[i]=0; for(int i=1;i<=n;++i) ++tax[rnk[i]]; for(int i=1;i<=m;++i) tax[i]+=tax[i-1]; for(int i=n;i;--i) sa[tax[rnk[tp[i]]]--]=tp[i]; } inline void Suffix_Sort() { for(int i=1;i<=n;++i) rnk[i]=s[i],tp[i]=i; Qsort(); for(int l=1,p=0;p<n;m=p,l<<=1) { p=0; for(int i=n-l+1;i<=n;++i) tp[++p]=i; for(int i=1;i<=n;++i) if(sa[i]>l) tp[++p]=sa[i]-l; Qsort(); for(int i=1;i<=n;++i) swap(rnk[i],tp[i]); rnk[sa[1]]=p=1; for(int i=2;i<=n;++i) rnk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+l]==tp[sa[i-1]+l])?p:++p; } } inline void Get_Height() { int j,k=0; for(int i=1;i<=n;++i) { if(k) --k; j=sa[rnk[i]-1]; while(j+k<=n&&i+k<=n&&s[i+k]==s[j+k]) ++k; ans-=k; } } int T; int main() { scanf("%d",&T); while(T--) { scanf("%s",s+1); n=strlen(s+1),m=N-1; ans=n*(n+1)/2; Suffix_Sort(); Get_Height(); cout<<ans<<'\n'; } return 0; } /* 2 CCCCC ABABA */