zoukankan      html  css  js  c++  java
  • SPOJ

    Distinct Substrings 

    Time Limit: 159MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu

    Description

    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.

    /*
     * SPOJ - DISUBSTR  Distinct Substrings
     * 求不同子串的个数
     *
     * 长度为n的字符串有n*(n+1)/2个子串,再减去相同的子串就行了
     * 对于子串,它肯定是一个后缀的前缀,如果height[i]==k,说明后缀i-1和后缀i有k个子串相同,
     * 这样减去它即可,即减去height数组的后n-1个即可
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 1000+100;
    
    int sa[MAXN];
    int t1[MAXN],t2[MAXN],c[MAXN];
    int Rank[MAXN],height[MAXN];
    void build_sa(int s[],int n,int m)
    {
        int i,j,p,*x=t1,*y=t2;
        for(i=0;i<m;i++)c[i]=0;
        for(i=0;i<n;i++)c[x[i]=s[i]]++;
        for(i=1;i<m;i++)c[i]+=c[i-1];
        for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
        for(j=1;j<=n;j<<=1)
        {
            p=0;
            for(i=n-j;i<n;i++)y[p++]=i;
            for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
            for(i=0;i<m;i++)c[i]=0;
            for(i=0;i<n;i++)c[x[y[i]]]++;
            for(i=1;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]+j]==y[sa[i]+j]?p-1:p++;
            if(p>=n)break;
            m=p;
        }
    }
    void getHeight(int s[],int n)
    {
        int i,j,k=0;
        for(i=0;i<=n;i++) Rank[sa[i]]=i;
        for(i=0;i<n;i++)
        {
            if(k)k--;
            j=sa[Rank[i]-1];
            while(s[i+k]==s[j+k])k++;
            height[Rank[i]]=k;
        }
    }
    char str[MAXN];
    int ss[MAXN];
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",str);
            int len=strlen(str);
            for(int i=0;i<len;i++) ss[i]=str[i];
            ss[len]=0;
            build_sa(ss,len+1,128);
            getHeight(ss,len);
            int ans=len*(len+1)/2;
            for(int i=2;i<=len;i++) ans-=height[i];
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    [转]对Lucene PhraseQuery的slop的理解
    Best jQuery Plugins of 2010
    15 jQuery Plugins To Create A User Friendly Tooltip
    Lucene:基于Java的全文检索引擎简介
    9 Powerful jQuery File Upload Plugins
    Coding Best Practices Using DateTime in the .NET Framework
    Best Image Croppers ready to use for web developers
    28 jQuery Zoom Plugins Creating Stunning Image Effect
    VS2005 + VSS2005 实现团队开发、源代码管理、版本控制(转)
    禁止状态栏显示超链
  • 原文地址:https://www.cnblogs.com/wangdongkai/p/5778026.html
Copyright © 2011-2022 走看看