SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct SubstringsProblem 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
- /*
- * SPOJ 694
- * 给定一个字符串,求不相同子串个数。
- * 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同子串个数。
- * 总数为n*(n+1)/2,再减掉height[i]的和就是答案 (原作写的是“-”,但我觉得是笔误)
- */
- #include <iostream>
- #include <string.h>
- #include <algorithm>
- #include <stdio.h>
- using namespace std;
- const int MAXN=;
- /*
- *suffix array
- *倍增算法 O(n*logn)
- *待排序数组长度为n,放在0~n-1中,在最后面补一个0
- *build_sa( ,n+1, );//注意是n+1;
- *getHeight(,n);
- *例如:
- *n = 8;
- *num[] = { 1, 1, 2, 1, 1, 1, 1, 2, $ };注意num最后一位为0,其他大于0
- *rank[] = { 4, 6, 8, 1, 2, 3, 5, 7, 0 };rank[0~n-1]为有效值,rank[n]必定为0无效值
- *sa[] = { 8, 3, 4, 5, 0, 6, 1, 7, 2 };sa[1~n]为有效值,sa[0]必定为n是无效值
- *height[]= { 0, 0, 3, 2, 3, 1, 2, 0, 1 };height[2~n]为有效值
- *
- */
- int sa[MAXN];//SA数组,表示将S的n个后缀从小到大排序后把排好序的
- //的后缀的开头位置顺次放入SA中
- int t1[MAXN],t2[MAXN],c[MAXN];//求SA数组需要的中间变量,不需要赋值
- int rank[MAXN],height[MAXN];
- //待排序的字符串放在s数组中,从s[0]到s[n-1],长度为n,且最大值小于m,
- //除s[n-1]外的所有s[i]都大于0,r[n-1]=0
- //函数结束以后结果放在sa数组中
- void build_sa(int s[],int n,int m)
- {
- int i,j,p,*x=t1,*y=t2;
- //第一轮基数排序,如果s的最大值很大,可改为快速排序
- for(i=;i<m;i++)c[i]=;
- for(i=;i<n;i++)c[x[i]=s[i]]++;
- for(i=;i<m;i++)c[i]+=c[i-];
- for(i=n-;i>=;i--)sa[--c[x[i]]]=i;
- for(j=;j<=n;j<<=)
- {
- p=;
- //直接利用sa数组排序第二关键字
- for(i=n-j;i<n;i++)y[p++]=i;//后面的j个数第二关键字为空的最小
- for(i=;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
- //这样数组y保存的就是按照第二关键字排序的结果
- //基数排序第一关键字
- for(i=;i<m;i++)c[i]=;
- for(i=;i<n;i++)c[x[y[i]]]++;
- for(i=;i<m;i++)c[i]+=c[i-];
- for(i=n-;i>=;i--)sa[--c[x[y[i]]]]=y[i];
- //根据sa和x数组计算新的x数组
- swap(x,y);
- p=;x[sa[]]=;
- for(i=;i<n;i++)
- x[sa[i]]=y[sa[i-]]==y[sa[i]] && y[sa[i-]+j]==y[sa[i]+j]?p-:p++;
- if(p>=n)break;
- m=p;//下次基数排序的最大值
- }
- }
- void getHeight(int s[],int n)
- {
- int i,j,k=;
- for(i=;i<=n;i++)rank[sa[i]]=i;
- for(i=;i<n;i++)
- {
- if(k)k--;
- j=sa[rank[i]-];
- while(s[i+k]==s[j+k])k++;
- height[rank[i]]=k;
- }
- }
- char str[MAXN];
- int s[MAXN];
- int main()
- {
- //freopen("in.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- int T;
- scanf("%d",&T);
- while(T--)
- {
- scanf("%s",str);
- int n=strlen(str);
- for(int i=;i<=n;i++)s[i]=str[i];
- build_sa(s,n+,);
- getHeight(s,n);
- int ans=n*(n+)/;
- for(int i=;i<=n;i++)ans-=height[i];
- printf("%d\n",ans);
- }
- return ;
- }
SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转的更多相关文章
- spoj 694. Distinct Substrings 后缀数组求不同子串的个数
题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...
- SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数
题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...
- SPOJ - DISUBSTR Distinct Substrings (后缀数组)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- SPOJ DISUBSTR Distinct Substrings 后缀数组
题意:统计母串中包含多少不同的子串 然后这是09年论文<后缀数组——处理字符串的有力工具>中有介绍 公式如下: 原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾 #in ...
- 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 ...
- SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )
题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...
- 后缀数组 SPOJ 694 Distinct Substrings
题目链接 题意:给定一个字符串,求不相同的子串的个数 分析:我们能知道后缀之间相同的前缀的长度,如果所有的后缀按照 suffix(sa[0]), suffix(sa[1]), suffix(sa[2] ...
- 【SPOJ – SUBST1】New Distinct Substrings 后缀数组
New Distinct Substrings 题意 给出T个字符串,问每个字符串有多少个不同的子串. 思路 字符串所有子串,可以看做由所有后缀的前缀组成. 按照后缀排序,遍历后缀,每次新增的前缀就是 ...
- spoj Distinct Substrings 后缀数组
给定一个字符串,求不相同的子串的个数. 假如给字符串“ABA";排列的子串可能: A B A AB BA ABA 共3*(3+1)/2=6种; 后缀数组表示时: A ABA BA 对于A和 ...
随机推荐
- spark新能优化之reduceBykey和groupBykey的使用
val counts = pairs.reduceByKey(_ + _) val counts = pairs.groupByKey().map(wordCounts => (wordCoun ...
- UVA-11468 Substring(AC自动机+DP)
题目大意:给一些模板串,一些字符的出现概率.问不会出现模板串的概率是多少. 题目分析:是比较简单的概率DP+AC自动机.利用全概率公式递推即可. 代码如下: # include<iostream ...
- Linux 的多线程编程的高效开发经验(转)
http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/ 背景 Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多 ...
- Linux驱动设计—— 内外存访问
本节对内外存访问做详细的介绍. 驱动程序加载成功的一个关键因素,就是内核能够为驱动程序分配足够的内存空间.这些空间一部分用于驱动程序必要的数据结构,另一部分用于数据的交换.同时,内核也应该具有访问外部 ...
- VC++ MFC橡皮筋技术
在MFC下绘制直线,使用橡皮筋技术,可以使直线效果跟随鼠标移动 //OnLButtionDown m_ptOrigin = m_ptEnd = point; //OnMouseMove ...
- compiler
http://www.lingcc.com/2012/05/16/12048/ a list of compiler books — 汗牛充栋的编译器参考资料 Posted on 2012年5月16日 ...
- 亲测 logminer挖掘
LogMiner两种使用类型,一种是使用源数据库的数据字典分析DML操作,别一种是摘取LogMiner数据字典到字典文件分析DDL操作.检查下suppplemental logging:SQL> ...
- 代码里面执行bat
public static void executeBat(String path) { try { File file = new File(path); ...
- 在Windows上安装Maven
下载 Maven 最新版本. http://maven.apache.org/download.cgi 1,下载包后,解压到相应特定位置. 2,将 [解压位置]/bin 加入到Path 3, ...
- 【Swift】读取文本文件字符串
var str:NSString = NSString.stringWithContentsOfFile(_srcouceFilePath,encoding:NSUTF8StringEncoding, ...