Distinct Substrings

题目大意:RT

 
分析:练手题目....后缀数组确实很强大.....多理解height数组, 切勿使用模版,后缀数组本身就有很多细节,多犯错更有利理解这个算法。
 
代码如下:
=====================================================================================================================
 
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

const int MAXN = 1007;

struct SuffixArr
{
    int tempx[MAXN], tempy[MAXN], text[MAXN];
    int rank[MAXN], sa[MAXN], sum[MAXN], height[MAXN];
    int *x, *y, N, MaxId;

    void GetText(char s[])
    {
        N = strlen(s)+1;
        x = tempx, y = tempy, MaxId=300;

        for(int i=0; i<N; i++)
        {
            text[i] = x[i] = (int)s[i];
            y[i] = i;
        }
    }
    bool cmp(int i, int len)
    {
        if(sa[i]+len>N || sa[i-1]+len>N)
            return false;
        if(y[sa[i]] != y[sa[i-1]] || y[sa[i]+len] != y[sa[i-1]+len])
            return false;

        return true;
    }
    void BaseSort()
    {
        for(int i=0; i<MaxId; i++)
            sum[i] = 0;
        for(int i=0; i<N; i++)
            sum[ x[ y[i] ] ] += 1;
        for(int i=1; i<MaxId; i++)
            sum[i] += sum[i-1];
        for(int i=N-1; i>=0; i--)
            sa[ --sum[ x[ y[i] ] ] ] = y[i];
    }
    void GetSa()
    {
        BaseSort();

        for(int len=1; len<=N; len<<=1)
        {
            int id = 0;

            for(int i=N-len; i<N; i++)
                y[id++] = i;
            for(int i=0; i<N; i++)if(sa[i] >= len)
                y[id++] = sa[i]-len;

            BaseSort();
            swap(x, y);
            x[ sa[0] ] = id = 0;

            for(int i=1; i<N; i++)
            {
                if(cmp(i, len) == true)
                    x[sa[i]] = id;
                else
                    x[sa[i]] = ++id;
            }

            MaxId = id+1;

            if(MaxId >= N)break;
        }
    }
    void GetHeight()
    {
        for(int i=0; i<N; i++)
            rank[sa[i]] = i;

        for(int k=0, i=0; i<N; i++)
        {
            if(!rank[i])
            {
                height[0] = k = 0;
                continue;
            }
            if(k)k--;

            int pre = sa[ rank[i]-1 ];

            while(text[i+k] == text[pre+k])
                k++;
            height[rank[i]] = k;
        }
    }
    int TotalSonArr()
    {
        int sum = 0;

        for(int i=0; i<N; i++)
            sum += N-sa[i]-1-height[i];

        return sum;
    }
    void debug(int p[])
    {
        for(int i=0; i<N; i++)
            printf("%d ", p[i]);
        printf("
");
    }
};

SuffixArr suf;
char s[MAXN];

int main()
{
    int T;

    scanf("%d", &T);

    while(T--)
    {
        scanf("%s", s);

        suf.GetText(s);
        suf.GetSa();
        suf.GetHeight();
        int ans = suf.TotalSonArr();

        printf("%d
", ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/liuxin13/p/4782031.html