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.
题解:
本题题意就是给你一个字符串,让你找它有多少不同的子串;
其实就是SAM的板题,只要求每一个状态点的longest[i]-longest[fa[i]]的和就行了。
但由于是后缀数组专题,还是用后缀数组写:
参考代码:
后缀自动机:
#include<bits/stdc++.h> using namespace std; #define PI acos(-1.0) #define mkp make_pair #define pii pair<int,int> #define fi first #define se second #define pb push_back typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=1e5+10; char s[maxn]; struct SAM{ ll ans; int fa[maxn<<1],l[maxn<<1],nxt[maxn<<1][26],last,cnt; void Init() { memset(nxt[1],0,sizeof(nxt[1])); last=cnt=1; ans=0; fa[1]=0;l[1]=0; } int NewNode() { ++cnt; memset(nxt[cnt],0,sizeof(nxt[cnt])); fa[cnt]=l[cnt]=0; return cnt; } void Add(int c) { int p=last,np=NewNode(); last=np;l[np]=l[p]+1; while(p&&!nxt[p][c]) nxt[p][c]=np,p=fa[p]; if(!p) fa[np]=1; else { int q=nxt[p][c]; if(l[q]==l[p]+1) fa[np]=q; else { int nq=NewNode(); memcpy(nxt[nq],nxt[q],sizeof(nxt[q])); fa[nq]=fa[q]; l[nq]=l[p]+1; fa[q]=fa[np]=nq; while(nxt[p][c]==q) nxt[p][c]=nq,p=fa[p]; } } ans+=(l[last]-l[fa[last]])*1ll; } void Query() { Init(); for(int i=0,len=strlen(s);i<len;++i) Add(s[i]-'A'); printf("%lld\n",ans); } } sam; int main() { int N; scanf("%d",&N); while(N--) { sam.Init(); scanf("%s",s); sam.Query(); } return 0; }