spoj New Distinct Substrings

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 <= 50000

Output

For each test case output one number saying the number of distinct substrings.

Example

Input:
2
CCCCC
ABABA

Output:
5
9

竟然卡log。。。害了我看了半天,改long long又tle。。。。
我不会基数排序。。。。。。。。。
n*(n+1)/2-lcp总和,因为相邻的两个sa的lcp肯定是这两个sa的最长前缀,又因为有相同前缀,肯定要减去,只用减一次就可以了,只重复了一次。。。
错误代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 50010
int n,k;
int sa[N],Rank[N],temp[N],lcp[N];
char s[N];
bool cp(int i,int j)
{
    if(Rank[i]!=Rank[j]) return Rank[i]<Rank[j];
    int ri=i+k<=n?Rank[i+k]:-1;
    int rj=j+k<=n?Rank[j+k]:-1;
    return ri<rj;
}
void Sa()
{
    for(int i=1;i<=n;i++)
    {
        sa[i]=i; Rank[i]=s[i];
    }
    for(k=1;k<=n;k<<=1)
    {
        sort(sa+1,sa+n+1,cp);
        temp[sa[1]]=0;
        for(int i=2;i<=n;i++) temp[sa[i]]=temp[sa[i-1]]+(cp(sa[i-1],sa[i]));
        for(int i=1;i<=n;i++) Rank[i]=temp[i];
    }
}
void Lcp()
{
    for(int i=1;i<=n;i++) Rank[sa[i]]=i;
    int h=0,ans=n*(n+1)/2;    
    for(int i=1;i<=n;i++)
    {
        int j=sa[Rank[i]-1];
        if(h>0) h--;
        for(;(i+h<=n&&j+h<=n);h++) if(s[i+h]!=s[j+h]) break;
        ans-=h;
    }
    printf("%d\n",ans);
} 
void solve()
{
    Sa(); Lcp(); 
}
int main()
{
    int T; scanf("%d",&T);
    while(T--)
    {
        scanf("%s",s+1);
        n=strlen(s+1);
        solve();
    }
    return 0;
}

 

posted @ 2017-01-13 22:33  19992147  阅读(172)  评论(0编辑  收藏  举报