HDU 3518 Boring counting[后缀数组]

题意:

找出原串中出现超过2次的子串的数目,每个子串出现多次时不可重叠。

分析:

枚举子串的长度len,找到满足连续的height[i]>=len的最左端 l 和最右端的位置 r,如果r-l>=len说明子串没有重叠。

View Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1005;
int N;
char s[maxn];
int sa[maxn],t[maxn],t2[maxn],c[maxn];
void suffix_sa(int n, int m)
{
    int i, *x=t, *y=t2;
    for (i=0; i<m; i++)  c[i] = 0;
    for (i=0; i<n; i++)  c[x[i]=s[i]]++;
    for (i=0; i<m; i++)  c[i] += c[i-1];
    for (i=n-1; i>=0; i--)  sa[--c[x[i]]] = i;
    for (int k=1; k<=n; k<<=1) {
        int p = 0;
        for (i=n-k; i<n; i++)  y[p++] = i;
        for (i=0; i<n; i++) if (sa[i] >= k) y[p++] = sa[i]-k;
        for (i=0; i<m; i++)  c[i] = 0;
        for (i=0; i<n; i++)  c[x[y[i]]]++;
        for (i=0; i<m; i++)  c[i] += c[i-1];
        for (i=n-1; i>=0; i--)  sa[--c[x[y[i]]]] = y[i];
        swap(x,y);
        p = 1; x[sa[0]] = 0;
        for (i=1; i<n; i++)
            x[sa[i]] = y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
        if (p>=n) break;
            m = p;
    }
}

int rank[maxn],height[maxn];
void getheight()
{
    int i, j, k=0;
    for (i=1; i<=N; i++)
        rank[sa[i]] = i;
    for (i=0; i<N; i++){
        if (k) k--;
        int j = sa[rank[i]-1];
        while (s[i+k] == s[j+k]) k++;
            height[rank[i]] = k;
    }
}

void solve()
{
    N = strlen(s);
    suffix_sa(N+1,'z'+1);
    getheight();
    int res = 0;
    int i, j, k, l, r;
    for (i=1; i<N/2+1; i++)
    {
        l = N,r = -1;
        for (j=2; j<=N; j++)
        {

            if (height[j]>=i)
            {
                r = max(r,max(sa[j-1],sa[j]));
                l = min(l,min(sa[j-1],sa[j]));
            }
            else if (height[j]<i)
            {
                if (r-l>=i)
                    res++;
                r = -1;
                l = N;
            }
        }
        if (r-l>=i)
            res++;
    }
    printf("%d\n",res);
}
int main()
{
    while (scanf("%s",s),s[0]!='#')
    {
        solve();
    }
    return 0;
}

 

posted @ 2013-02-15 17:59  'wind  阅读(260)  评论(0编辑  收藏  举报