Given a string, we need to find the total number of its distinct substrings.
Input
T- number of test cases. T<=20;
Each test case consists of one string, whose length is <= 1000
Output
For each test case output one number saying the number of distinct substrings.
Example
Sample Input:
2
CCCCC
ABABA
Sample Output:
5
9
Explanation for the testcase with string ABABA:
len=1 : A,B
len=2 : AB,BA
len=3 : ABA,BAB
len=4 : ABAB,BABA
len=5 : ABABA
Thus, total number of distinct substrings is 9.
题意:
求出大写的字符串里不同的子串。默写了一遍后缀自动机。今天主要是练习后缀数组。
注意:
- 注意是大写还是小写;
- 注意init初始化的时候没有一次性memset,所以下面要把每个新出现的点memset。不要搞忘。
后缀自动机:
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int maxn=10000; struct SAM { int ch[maxn][26],fa[maxn],maxlen[maxn],Last,sz; void init() { sz=Last=1; fa[1]=maxlen[1]=0; memset(ch[1],0,sizeof(ch[1])); } void add(int x) { int np=++sz,p=Last;Last=np; memset(ch[np],0,sizeof(ch[np])); maxlen[np]=maxlen[p]+1; while(p&&!ch[p][x]) ch[p][x]=np,p=fa[p]; if(!p) fa[np]=1; else { int q=ch[p][x]; if(maxlen[p]+1==maxlen[q]) fa[np]=q; else { int nq=++sz; memcpy(ch[nq],ch[q],sizeof(ch[q])); maxlen[nq]=maxlen[p]+1; fa[nq]=fa[q]; fa[q]=fa[np]=nq; while(p&&ch[p][x]==q) ch[p][x]=nq,p=fa[p]; } } } }; SAM Sam; int main() { char chr[maxn]; int T,ans,i,L; scanf("%d",&T); while(T--){ Sam.init();ans=0; scanf("%s",chr); L=strlen(chr); for(i=0;i<L;i++) Sam.add(chr[i]-'A'); for(i=1;i<=Sam.sz;i++) ans+=Sam.maxlen[i]-Sam.maxlen[Sam.fa[i]]; printf("%d\n",ans); } return 0; }