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;
}
View Code

相关文章: