694. Distinct Substrings

Problem code: DISUBSTR

 

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.

链接:http://www.cnblogs.com/kuangbin/archive/2013/04/24/3039634.html

  1. /*
  2. * SPOJ 694
  3. * 给定一个字符串,求不相同子串个数。
  4. * 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同子串个数。
  5. * 总数为n*(n+1)/2,再减掉height[i]的和就是答案 (原作写的是“-”,但我觉得是笔误)
  6. */
  7.  
  8. #include <iostream>
  9. #include <string.h>
  10. #include <algorithm>
  11. #include <stdio.h>
  12. using namespace std;
  13. const int MAXN=;
  14.  
  15. /*
  16. *suffix array
  17. *倍增算法 O(n*logn)
  18. *待排序数组长度为n,放在0~n-1中,在最后面补一个0
  19. *build_sa( ,n+1, );//注意是n+1;
  20. *getHeight(,n);
  21. *例如:
  22. *n = 8;
  23. *num[] = { 1, 1, 2, 1, 1, 1, 1, 2, $ };注意num最后一位为0,其他大于0
  24. *rank[] = { 4, 6, 8, 1, 2, 3, 5, 7, 0 };rank[0~n-1]为有效值,rank[n]必定为0无效值
  25. *sa[] = { 8, 3, 4, 5, 0, 6, 1, 7, 2 };sa[1~n]为有效值,sa[0]必定为n是无效值
  26. *height[]= { 0, 0, 3, 2, 3, 1, 2, 0, 1 };height[2~n]为有效值
  27. *
  28. */
  29.  
  30. int sa[MAXN];//SA数组,表示将S的n个后缀从小到大排序后把排好序的
  31. //的后缀的开头位置顺次放入SA中
  32. int t1[MAXN],t2[MAXN],c[MAXN];//求SA数组需要的中间变量,不需要赋值
  33. int rank[MAXN],height[MAXN];
  34. //待排序的字符串放在s数组中,从s[0]到s[n-1],长度为n,且最大值小于m,
  35. //除s[n-1]外的所有s[i]都大于0,r[n-1]=0
  36. //函数结束以后结果放在sa数组中
  37. void build_sa(int s[],int n,int m)
  38. {
  39. int i,j,p,*x=t1,*y=t2;
  40. //第一轮基数排序,如果s的最大值很大,可改为快速排序
  41. for(i=;i<m;i++)c[i]=;
  42. for(i=;i<n;i++)c[x[i]=s[i]]++;
  43. for(i=;i<m;i++)c[i]+=c[i-];
  44. for(i=n-;i>=;i--)sa[--c[x[i]]]=i;
  45. for(j=;j<=n;j<<=)
  46. {
  47. p=;
  48. //直接利用sa数组排序第二关键字
  49. for(i=n-j;i<n;i++)y[p++]=i;//后面的j个数第二关键字为空的最小
  50. for(i=;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
  51. //这样数组y保存的就是按照第二关键字排序的结果
  52. //基数排序第一关键字
  53. for(i=;i<m;i++)c[i]=;
  54. for(i=;i<n;i++)c[x[y[i]]]++;
  55. for(i=;i<m;i++)c[i]+=c[i-];
  56. for(i=n-;i>=;i--)sa[--c[x[y[i]]]]=y[i];
  57. //根据sa和x数组计算新的x数组
  58. swap(x,y);
  59. p=;x[sa[]]=;
  60. for(i=;i<n;i++)
  61. x[sa[i]]=y[sa[i-]]==y[sa[i]] && y[sa[i-]+j]==y[sa[i]+j]?p-:p++;
  62. if(p>=n)break;
  63. m=p;//下次基数排序的最大值
  64. }
  65. }
  66. void getHeight(int s[],int n)
  67. {
  68. int i,j,k=;
  69. for(i=;i<=n;i++)rank[sa[i]]=i;
  70. for(i=;i<n;i++)
  71. {
  72. if(k)k--;
  73. j=sa[rank[i]-];
  74. while(s[i+k]==s[j+k])k++;
  75. height[rank[i]]=k;
  76. }
  77. }
  78.  
  79. char str[MAXN];
  80. int s[MAXN];
  81.  
  82. int main()
  83. {
  84. //freopen("in.txt","r",stdin);
  85. //freopen("out.txt","w",stdout);
  86. int T;
  87. scanf("%d",&T);
  88. while(T--)
  89. {
  90. scanf("%s",str);
  91. int n=strlen(str);
  92. for(int i=;i<=n;i++)s[i]=str[i];
  93. build_sa(s,n+,);
  94. getHeight(s,n);
  95. int ans=n*(n+)/;
  96. for(int i=;i<=n;i++)ans-=height[i];
  97. printf("%d\n",ans);
  98. }
  99. return ;
  100. }

SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转的更多相关文章

  1. spoj 694. Distinct Substrings 后缀数组求不同子串的个数

    题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...

  2. SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数

    题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...

  3. SPOJ - DISUBSTR Distinct Substrings (后缀数组)

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

  4. SPOJ DISUBSTR Distinct Substrings 后缀数组

    题意:统计母串中包含多少不同的子串 然后这是09年论文<后缀数组——处理字符串的有力工具>中有介绍 公式如下: 原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾 #in ...

  5. SPOJ 694 Distinct Substrings/SPOJ 705 New Distinct Substrings(后缀数组)

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

  6. SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )

    题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...

  7. 后缀数组 SPOJ 694 Distinct Substrings

    题目链接 题意:给定一个字符串,求不相同的子串的个数 分析:我们能知道后缀之间相同的前缀的长度,如果所有的后缀按照 suffix(sa[0]), suffix(sa[1]), suffix(sa[2] ...

  8. 【SPOJ – SUBST1】New Distinct Substrings 后缀数组

    New Distinct Substrings 题意 给出T个字符串,问每个字符串有多少个不同的子串. 思路 字符串所有子串,可以看做由所有后缀的前缀组成. 按照后缀排序,遍历后缀,每次新增的前缀就是 ...

  9. spoj Distinct Substrings 后缀数组

    给定一个字符串,求不相同的子串的个数. 假如给字符串“ABA";排列的子串可能: A B A AB  BA ABA 共3*(3+1)/2=6种; 后缀数组表示时: A ABA BA 对于A和 ...

随机推荐

  1. spark新能优化之reduceBykey和groupBykey的使用

    val counts = pairs.reduceByKey(_ + _) val counts = pairs.groupByKey().map(wordCounts => (wordCoun ...

  2. UVA-11468 Substring(AC自动机+DP)

    题目大意:给一些模板串,一些字符的出现概率.问不会出现模板串的概率是多少. 题目分析:是比较简单的概率DP+AC自动机.利用全概率公式递推即可. 代码如下: # include<iostream ...

  3. Linux 的多线程编程的高效开发经验(转)

    http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/ 背景 Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多 ...

  4. Linux驱动设计—— 内外存访问

    本节对内外存访问做详细的介绍. 驱动程序加载成功的一个关键因素,就是内核能够为驱动程序分配足够的内存空间.这些空间一部分用于驱动程序必要的数据结构,另一部分用于数据的交换.同时,内核也应该具有访问外部 ...

  5. VC++ MFC橡皮筋技术

    在MFC下绘制直线,使用橡皮筋技术,可以使直线效果跟随鼠标移动 //OnLButtionDown        m_ptOrigin = m_ptEnd = point;  //OnMouseMove ...

  6. compiler

    http://www.lingcc.com/2012/05/16/12048/ a list of compiler books — 汗牛充栋的编译器参考资料 Posted on 2012年5月16日 ...

  7. 亲测 logminer挖掘

    LogMiner两种使用类型,一种是使用源数据库的数据字典分析DML操作,别一种是摘取LogMiner数据字典到字典文件分析DDL操作.检查下suppplemental logging:SQL> ...

  8. 代码里面执行bat

    public static void executeBat(String path) {        try {            File file = new File(path);     ...

  9. 在Windows上安装Maven

      下载 Maven 最新版本. http://maven.apache.org/download.cgi   1,下载包后,解压到相应特定位置. 2,将 [解压位置]/bin  加入到Path 3, ...

  10. 【Swift】读取文本文件字符串

    var str:NSString = NSString.stringWithContentsOfFile(_srcouceFilePath,encoding:NSUTF8StringEncoding, ...