Distinct Substrings SPOJ - 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.
那么这个问题就转化成了所有后缀中不相同的前缀一共有多少个
但是有重复的,重复个数就是height[i]
所有不重复前缀是n-sa[i]+1-height[i]
这样的话就会导致最后的答案少计算
这个新长度的字符串求解
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb))
5 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2)
6 using namespace std;
7 const int N = 1005;
8 int c[N],sa[N*3];
9 int ranks[N*3], height[N*3],s[N];
10 char str[N];
11 bool pan(int *x,int i,int j,int k,int n)
12 {
13 int ti=i+k<n?x[i+k]:-1;
14 int tj=j+k<n?x[j+k]:-1;
15 return x[i]==x[j]&&ti==tj;
16 }
17 void build_SA(int n,int r)
18 {
19 int *x=ranks,*y=height;
20 for(int i=0; i<r; i++)c[i]=0;
21 for(int i=0; i<n; i++)c[s[i]]++;
22 for(int i=1; i<r; i++)c[i]+=c[i-1];
23 for(int i=n-1; i>=0; i--)sa[--c[s[i]]]=i;
24 r=1;
25 x[sa[0]]=0;
26 for(int i=1; i<n; i++)
27 x[sa[i]]=s[sa[i]]==s[sa[i-1]]?r-1:r++;
28 for(int k=1; r<n; k<<=1)
29 {
30 int yn=0;
31 for(int i=n-k; i<n; i++)y[yn++]=i;
32 for(int i=0; i<n; i++)
33 if(sa[i]>=k)y[yn++]=sa[i]-k;
34 for(int i=0; i<r; i++)c[i]=0;
35 for(int i=0; i<n; i++)++c[x[y[i]]];
36 for(int i=1; i<r; i++)c[i]+=c[i-1];
37 for(int i=n-1; i>=0; i--)sa[--c[x[y[i]]]]=y[i];
38 swap(x,y);
39 r=1;
40 x[sa[0]]=0;
41 for(int i=1; i<n; i++)
42 x[sa[i]]=pan(y,sa[i],sa[i-1],k,n)?r-1:r++;
43 }
44 for(int i=0; i<n; i++)ranks[i]=x[i];
45 }
46 void get_height(int n)
47 {
48 int i,j,k=0;
49 for(i=1; i<=n; i++)ranks[sa[i]]=i;
50 for(i=0; i<n; i++)
51 {
52 if(k)k--;
53 else k=0;
54 j=sa[ranks[i]-1];
55 while(s[i+k]==s[j+k])k++;
56 height[ranks[i]]=k;
57 }
58 }
59 int main() {
60 int t;
61 scanf("%d", &t);
62 while (t--) {
63 scanf("%s", str);
64 int len = strlen(str);
65 for (int i = 0; i < len; i++)
66 s[i] = (int)str[i];
67 s[len] = 0;
68 build_SA(len+1,200);
69 get_height(len);
70 int res = 0;
71 for (int i = 1; i <= len; i++)
72 //printf("%d ",height[i]),
73 res += ((len-1) - sa[i]+1 - height[i]);
74 printf("%d\n", res);
75 }
76 return 0;
77 }
形成的height就是结果
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb))
5 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2)
6 using namespace std;
7 const int N = 1005;
8 int c[N],sa[N*3];
9 int ranks[N*3], height[N*3],s[N];
10 char str[N];
11 bool pan(int *x,int i,int j,int k,int n)
12 {
13 int ti=i+k<n?x[i+k]:-1;
14 int tj=j+k<n?x[j+k]:-1;
15 return x[i]==x[j]&&ti==tj;
16 }
17 void build_SA(int n,int r)
18 {
19 int *x=ranks,*y=height;
20 for(int i=0; i<r; i++)c[i]=0;
21 for(int i=0; i<n; i++)c[s[i]]++;
22 for(int i=1; i<r; i++)c[i]+=c[i-1];
23 for(int i=n-1; i>=0; i--)sa[--c[s[i]]]=i;
24 r=1;
25 x[sa[0]]=0;
26 for(int i=1; i<n; i++)
27 x[sa[i]]=s[sa[i]]==s[sa[i-1]]?r-1:r++;
28 for(int k=1; r<n; k<<=1)
29 {
30 int yn=0;
31 for(int i=n-k; i<n; i++)y[yn++]=i;
32 for(int i=0; i<n; i++)
33 if(sa[i]>=k)y[yn++]=sa[i]-k;
34 for(int i=0; i<r; i++)c[i]=0;
35 for(int i=0; i<n; i++)++c[x[y[i]]];
36 for(int i=1; i<r; i++)c[i]+=c[i-1];
37 for(int i=n-1; i>=0; i--)sa[--c[x[y[i]]]]=y[i];
38 swap(x,y);
39 r=1;
40 x[sa[0]]=0;
41 for(int i=1; i<n; i++)
42 x[sa[i]]=pan(y,sa[i],sa[i-1],k,n)?r-1:r++;
43 }
44 for(int i=0; i<n; i++)ranks[i]=x[i];
45 }
46 void get_height(int n)
47 {
48 int i,j,k=0;
49 for(i=1; i<=n; i++)ranks[sa[i]]=i;
50 for(i=0; i<n; i++)
51 {
52 if(k)k--;
53 else k=0;
54 j=sa[ranks[i]-1];
55 while(s[i+k]==s[j+k])k++;
56 height[ranks[i]]=k;
57 }
58 }
59 int main()
60 {
61 int t;
62 scanf("%d", &t);
63 while (t--)
64 {
65 scanf("%s", str);
66 int len = strlen(str);
67 for (int i = 0; i < len; i++)
68 s[i] = (int)str[i];
69 s[len] = 0;
70 build_SA(len+1,200);
71 get_height(len);
72 int res = ((len+1)*len)/2;
73 for (int i = 2; i <= len; i++)
74 //printf("%d ",height[i]),
75 res -= height[i];
76 printf("%d\n", res);
77 }
78 return 0;
79 }
Distinct Substrings SPOJ - DISUBSTR 后缀数组的更多相关文章
- Distinct Substrings SPOJ - DISUBSTR(后缀数组水题)
求不重复的子串个数 用所有的减去height就好了 推出来的... #include <iostream> #include <cstdio> #include <sst ...
- Spoj-DISUBSTR - Distinct Substrings~New Distinct Substrings SPOJ - SUBST1~(后缀数组求解子串个数)
Spoj-DISUBSTR - Distinct Substrings New Distinct Substrings SPOJ - SUBST1 我是根据kuangbin的后缀数组专题来的 这两题题 ...
- 705. New Distinct Substrings spoj(后缀数组求所有不同子串)
705. New Distinct Substrings Problem code: SUBST1 Given a string, we need to find the total number o ...
- SPOJ DISUBSTR 后缀数组
题目链接:http://www.spoj.com/problems/DISUBSTR/en/ 题意:给定一个字符串,求不相同的子串个数. 思路:直接根据09年oi论文<<后缀数组——出来字 ...
- SPOJ DISUBSTR ——后缀数组
[题目分析] 后缀数组模板题. 由于height数组存在RMQ的性质. 那么对于一个后缀,与前面相同的串总共有h[i]+sa[i]个.然后求和即可. [代码](模板来自Claris,这个板子太漂亮了) ...
- [spoj DISUBSTR]后缀数组统计不同子串个数
题目链接:https://vjudge.net/contest/70655#problem/C 后缀数组的又一神奇应用.不同子串的个数,实际上就是所有后缀的不同前缀的个数. 考虑所有的后缀按照rank ...
- 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 ...
- Distinct Substrings(spoj694)(sam(后缀自动机)||sa(后缀数组))
Given a string, we need to find the total number of its distinct substrings. Input \(T-\) number of ...
- SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机
SPOJ694 DISUBSTR 题目描述: Given a string, we need to find the total number of its distinct substrings. ...
随机推荐
- 【Spring】XML方式实现(无参构造 有参构造)和注解方式实现 IoC
文章目录 Spring IoC的实现方式 XML方式实现 通过无参构造方法来创建 1.编写一个User实体类 2.编写我们的spring文件 3.测试类 UserTest.java 4.测试结果 通过 ...
- mysql .sock丢时候如何链接数据库
在mysql服务器本机上链接mysql数据库时,经常会噢出现mysql.sock不存在,导致无法链接的问题,这是因为如果指定localhost作为一个主机名,则mysqladmin默认使用unix套接 ...
- WMIC 查看bios配置信息
如何查看我们的主板上的BIOS信息呢?有办法,不用安装任何软件,只需要windows自带的命令提示符就行,哈哈 WMIC BIOS LIST FULL /FORMAT:VALUE 如果第一次使用wmi ...
- Table controls and tabstrip controls
本文转载自http://www.cnblogs.com/clsoho/archive/2010/01/21/1653268.html ONTROLS Syntax Forms Declaration ...
- Ice系列--傻瓜式服务开发IceBox
前言 相信大家在没有接触过框架之前,都自己或多或少的开发过一些应用服务.每个应用服务除了业务配置还有很多环境配置,资源配置等,这些跟部署相关的配置.服务跟配置文件是一种静态绑定的方式,更新配置还需要重 ...
- DockerFile关键字相关作用以及解释
Dockerfile 关键字 作用 备注 FROM 指定父镜像 指定dockerfile基于那个image构建 MAINTAINER 作者信息 用来标明这个dockerfile谁写的 LABEL 标签 ...
- uni-app开发经验分享十二: Android平台应用启动时读写手机存储、访问设备信息(如IMEI)等权限策略及提示信息
Android平台从6.0(API23)开始系统对权限的管理更加严格,所有涉及敏感权限都需要用户授权允许才能获取.因此一些应用基础业务逻辑需要的权限会在应用启动时申请,并引导用户允许. 读写手机存储权 ...
- 参数模型检验过滤器 .NetCore版
最近学习 .NETCore3.1,发现过滤器的命名空间有变化. 除此以外一些方法的名称和使用方式也有变动,正好重写一下. 过滤器的命名空间的变化 原先:System.Web.Http.Filters; ...
- PCB导线长宽与电源压降
为了计算PCB中电源线走线后的压降,需要知道PCB中使用的铜的电阻率, PCB板中的铜是直接贴上去的铜箔,因此可以当成纯铜(我问了PCB打样的厂家他们的铜的电阻率,但是他们给我说不知道,所以干脆就当成 ...
- JavaScript中的构造函数和原型!
JavaScript中的原型! 原型的内容是涉及到JavaScript中的构造函数的 每一个构造函数都有一个原型对象!prototype 他的作用是 共享方法!还可以扩展内置对象[对原来的内置对象进行 ...