spoj694 DISUBSTR
来源:互联网 发布:天地知我心二 编辑:程序博客网 时间:2024/05/21 12:40
DISUBSTR - Distinct Substrings
Description
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.
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.
题目大意
给定一个字符串,求不相同的子串的个数。
题解
论文中例5,比较简单的一道模板题。
考虑每个子串对应一个后缀的前缀,题目就是求所有后缀不相同的前缀的个数。按照sa的顺序计算每个后缀,那么第sa[i]个后缀对答案的贡献就是
#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int N = 1000 + 10;char s[N];int t, n, a[N];int v[N], sa[2][N], rk[2][N], ht[N], p, q, k, ans;void init(){ scanf("%s", s+1); n = strlen(s+1); for(int i = 1; i <= n; i++) a[i] = (int) s[i]; memset(sa, 0, sizeof(sa)); memset(rk, 0, sizeof(rk)); memset(ht, 0, sizeof(ht)); memset(v, 0, sizeof(v)); ans = 0;}void calsa(int *sa1, int *rk1, int *sa2, int *rk2){ for(int i = 1; i <= n; i++) v[rk1[sa1[i]]] = i; for(int i = n; i >= 1; i--) if(sa1[i] > k) sa2[v[rk1[sa1[i]-k]]--] = sa1[i] - k; for(int i = n-k+1; i <= n; i++) sa2[v[rk1[i]]--] = i; for(int i = 1; i <= n; i++) rk2[sa2[i]] = rk2[sa2[i-1]] + (rk1[sa2[i-1]] != rk1[sa2[i]] || rk1[sa2[i-1]+k] != rk1[sa2[i]+k]);}void calheight(){ int k = 0; for(int i = 1; i <= n; i++){ if(k) k--; int j = sa[p][rk[p][i]-1]; while(a[i+k] == a[j+k]) k++; ht[rk[p][i]] = k; }}void work(){ scanf("%d", &t); while(t--){ init(); p = 0, q = 1; for(int i = 1; i <= n; i++) v[a[i]]++; for(int i = 1; i <= 128; i++) v[i] += v[i-1]; for(int i = 1; i <= n; i++) sa[p][v[a[i]]--] = i; for(int i = 1; i <= n; i++) rk[p][sa[p][i]] = rk[p][sa[p][i-1]] + (a[sa[p][i]] != a[sa[p][i-1]]); memset(v, 0, sizeof(v)); k = 1; while(k < n){ calsa(sa[p], rk[p], sa[q], rk[q]); p ^= 1, q ^= 1, k <<= 1; } calheight(); for(int i = 1; i <= n; i++) ans += n - sa[p][i] + 1 - ht[i]; printf("%d\n", ans); }}int main(){ work(); return 0;}
0 0
- spoj694 DISUBSTR
- SPOJ694&&SPOJ705 DISUBSTR
- SPOJ694--- DISUBSTR - Distinct Substrings(后缀数组)
- 【后缀数组】【不同子串个数】DISUBSTR spoj694/705
- SPOJ DISUBSTR
- SPOJ DISUBSTR
- spoj694 Distinct Substrings
- spoj694后缀树组
- poj 1743及spoj694
- SPOJ694----后缀数组
- spoj694之后缀数组
- 后缀数组入门 SPOJ694
- spoj694 Distinct Substrings
- SPOJ DISUBSTR Distinct Substrings
- SPOJ DISUBSTR Distinct Substrings
- SPOJ DISUBSTR(后缀数组)
- SPOJ - DISUBSTR Distinct Substrings
- SPOJ DISUBSTR Distinct Substrings
- PAT A1078 hashing (25)
- C# 设计模式巩固笔记
- windows消息机制(MFC)
- Flask 之模板
- js--DOM--常用的节点类型
- spoj694 DISUBSTR
- 判断字符串是否为回文
- MySQL的备份与还原与索引、视图、存储过程与权限
- codeforce round 399# C
- Unity-UGUI性能优化UWA重点讲解
- Go语言技巧:使用for range time.Tick()固定间隔时间执行
- A Knowledge-Grounded Neural Conversation Model
- 第一个android应用——音乐下载
- [LeetCode] 78. Subsets