zoukankan      html  css  js  c++  java
  • SP694 DISUBSTR

    题意翻译

    给定一个字符串,求该字符串含有的本质不同的子串数量。

    题目描述

    Given a string, we need to find the total number of its distinct substrings.

    输入输出格式

    输入格式:

    T- number of test cases. T<=20;
    Each test case consists of one string, whose length is <= 1000

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    
      2
    
      CCCCC
    
      ABABA
    输出样例#1: 复制
    
      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.
    


    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N=1e3+5;
    
    char s[N];
    int n,m,ans;
    int rnk[N],sa[N],tax[N],tp[N];
    
    inline void Qsort()
    {
        for(int i=1;i<=m;++i)
            tax[i]=0;
        for(int i=1;i<=n;++i)
            ++tax[rnk[i]];
        for(int i=1;i<=m;++i)
            tax[i]+=tax[i-1];
        for(int i=n;i;--i)
            sa[tax[rnk[tp[i]]]--]=tp[i];
    }
    
    inline void Suffix_Sort()
    {
        for(int i=1;i<=n;++i)
            rnk[i]=s[i],tp[i]=i;
        Qsort();
        for(int l=1,p=0;p<n;m=p,l<<=1)
        {
            p=0;
            for(int i=n-l+1;i<=n;++i)
                tp[++p]=i;
            for(int i=1;i<=n;++i)
                if(sa[i]>l)
                    tp[++p]=sa[i]-l;
            Qsort();
            for(int i=1;i<=n;++i)
                swap(rnk[i],tp[i]);
            rnk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)
                rnk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+l]==tp[sa[i-1]+l])?p:++p;
        }
    }
    
    inline void Get_Height()
    {
        int j,k=0;
        for(int i=1;i<=n;++i)
        {
            if(k)
                --k;
            j=sa[rnk[i]-1];
            while(j+k<=n&&i+k<=n&&s[i+k]==s[j+k])
                ++k;
            ans-=k;
        }
    }
    
    int T;
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",s+1);
            n=strlen(s+1),m=N-1;
            ans=n*(n+1)/2;
            Suffix_Sort();
            Get_Height();
            cout<<ans<<'
    ';
        }
        return 0;
    }
    /*
    2
    CCCCC
    ABABA
    */
  • 相关阅读:
    JS的Document属性和方法小结
    机器学习笔记——最小二乘法
    c语言中printf()函数中的参数计算顺序
    机器学习笔记——拉格朗日乘子法和KKT条件
    Linux bash笔记
    java.util.ConcurrentModificationException的解决办法
    浅谈对java中传参问题的理解
    机器学习笔记——t分布知识点总结
    机器学习笔记——测试集和验证集的区别
    java中对HashMap遍历的方式
  • 原文地址:https://www.cnblogs.com/lovewhy/p/9633608.html
Copyright © 2011-2022 走看看