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. ...
随机推荐
- Azure Terraform(四)状态文件存储
一,引言 我们都知道在执行部署计划之后,当前目录中就产生了名叫 "" 的 Terraform 的状态文件,该文件中记录了已部署资源的状态.默认情况下,在执行部署计划后,Terraf ...
- http-请求和响应报文的构成
请求的构成: 1)请求方法URI协议/版本 2)请求头(Request Header) 3)请求正文 1)请求方法URI协议/版本 Request URL: http://localhost:8080 ...
- 【Oracle】权限相关
系统权限 SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'CHAXUN' UNION ALL SELECT * FROM DBA_SYS_PRIVS WHER ...
- buuctf刷题之旅—web—EasySQL
打开环境,发现依旧是sql注入 GitHub上有源码(https://github.com/team-su/SUCTF-2019/tree/master/Web/easy_sql) index.php ...
- SAP GUI用颜色区分不同的系统
对于经常打开多个窗口的SAP用户,有时候可能同时登录了生产机.测试机和开发机,为了避免误操作,比如在测试要执行的操作,结果在生产机做了,结果可想而知. 虽然可以通过右下角查看再去判断,但是总是没有通过 ...
- web dynpro配置注意事项
如果你想使用web dynpro 开发的应用,但是发现浏览器报错,那么你按照下面的步骤逐一进行检查吧.特别是返回的500错误,或者是你发现浏览器的地址栏中以http://<hostname> ...
- python爬虫如何提高效率
开启线程池: 线程池 asyncio 特殊的函数 协程 任务对象 任务对象绑定 事件循环 from multiprocessing.dummy import Pool map(func,alist): ...
- 🙈 如何隐藏你的热更新 bundle 文件?
如果你喜欢我写的文章,可以把我的公众号设为星标 ,这样每次有更新就可以及时推送给你啦. 前段时间我们公司的一个大佬从一些渠道得知了一些小道消息,某国民级 APP 因为 Apple App Store ...
- 抛弃 .NET 经典错误:object null reference , 使用安全扩展方法? 希望对大家有帮助---Bitter.Frame 引用类型的安全转换
还是一样,我不喜欢长篇大论,除非关乎我设计思想领域的文章.大家过来看,都是想节省时间,能用白话表达的内容,绝不长篇大论.能直接上核心代码的,绝不上混淆代码. 长期从事 .NET 工作的人都知道..NE ...
- There are only two hard things in Computer Science: cache invalidation and naming things.
TwoHardThings https://martinfowler.com/bliki/TwoHardThings.html https://github.com/cch123/golang-not ...