SPOJ New Distinct Substrings(后缀数组)
2017-07-26 18:00
381 查看
Given a string, we need to find the total number of its distinct substrings.
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
For each test case output one number saying the number of distinct substrings.
题意:给你一个字符串,问你他所有子串中,有多少种不同的。
一个字符串任意一个后缀的前缀都是字符串的子串,所有的后缀的所有前缀,就是字符串的所有子串。
这样我们要求有多少种不同的子串,就可以用子串的总数减去重复子串的个数。
比如第二个样例,按排名把所有后缀排一下:
A
ABA
ABABA
BA
BABA
第一个后缀前面没有后缀了,所以不会与前面的重复,对于第二个后缀,重复的子串就是A,第三个后缀,与前面重复的子串就是A,AB,ABA,可以发现这就是最长公共前缀的长度,也就是height数组的值。
所以最后的答案就是 所有子串的总数 n*(n+1)/ 2 - sigma(heght[i])
Given a string, we need to find the total number of its distinct substrings.
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
For each test case output one number saying the number of distinct substrings.
Input
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
Output
For each test case output one number saying the number of distinct substrings.
Example
Input: 2 CCCCC ABABA Output: 5 9
题意:给你一个字符串,问你他所有子串中,有多少种不同的。
一个字符串任意一个后缀的前缀都是字符串的子串,所有的后缀的所有前缀,就是字符串的所有子串。
这样我们要求有多少种不同的子串,就可以用子串的总数减去重复子串的个数。
比如第二个样例,按排名把所有后缀排一下:
A
ABA
ABABA
BA
BABA
第一个后缀前面没有后缀了,所以不会与前面的重复,对于第二个后缀,重复的子串就是A,第三个后缀,与前面重复的子串就是A,AB,ABA,可以发现这就是最长公共前缀的长度,也就是height数组的值。
所以最后的答案就是 所有子串的总数 n*(n+1)/ 2 - sigma(heght[i])
#include <cstdio> #include <cstring> #include<iostream> #include <algorithm> #define LL long long using namespace std; const int MAXN = 50010; int SA[MAXN], Rank[MAXN], Height[MAXN], tax[MAXN], tp[MAXN], a[MAXN], n, m; char str[MAXN]; void RSort() { for (int i = 0; i <= m; i ++) tax[i] = 0; for (int i = 1; i <= n; i ++) tax[Rank[tp[i]]] ++; for (int i = 1; i <= m; i ++) tax[i] += tax[i-1]; for (int i = n; i >= 1; i --) SA[tax[Rank[tp[i]]] --] = tp[i]; } int cmp(int *f, int x, int y, int w) { return f[x] == f[y] && f[x + w] == f[y + w]; } void Suffix() { for (int i = 1; i <= n; i ++) Rank[i] = a[i], tp[i] = i; m = 156 ,RSort(); for (int w = 1, p = 1, i; p < n; w += w, m = p) { for (p = 0, i = n - w + 1; i <= n; i ++) tp[++ p] = i; for (i = 1; i <= n; i ++) if (SA[i] > w) tp[++ p] = SA[i] - w; RSort(), swap(Rank, tp), Rank[SA[1]] = p = 1; for (i = 2; i <= n; i ++) Rank[SA[i]] = cmp(tp, SA[i], SA[i - 1], w) ? p : ++ p; } int j, k = 0; for(int i = 1; i <= n; Height[Rank[i ++]] = k) for( k = k ? k - 1 : k, j = SA[Rank[i] - 1]; a[i + k] == a[j + k]; ++ k); } void Init() { n = strlen(str+1); for(int i=1;i<=n;i++) a[i] = str[i]; Suffix(); } int k; int main(void) { int T,i,j; scanf("%d",&T); while(T--) { scanf("%s",str+1); Init(); LL ans = (LL)n*(n+1)/2; for(i=2;i<=n;i++) ans -= Height[i]; printf("%lld\n",ans); } return 0; }
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 <= 50000
Output
For each test case output one number saying the number of distinct substrings.
Example
Input: 2 CCCCC ABABA Output: 5 9
相关文章推荐
- SPOJ 694 Distinct Substrings/SPOJ 705 New Distinct Substrings(后缀数组)
- SPOJ 694、705 Distinct Substrings 、 New Distinct Substrings (后缀数组)
- SPOJ - SUBST1 New Distinct Substrings 后缀数组
- 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)
- SPOJ_705_New Distinct Substrings_后缀数组
- 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)
- SPOJ 705 New Distinct Substrings 后缀数组
- 后缀数组:SPOJ SUBST1 - New Distinct Substrings
- SPOJ 705 New Distinct Substrings (后缀数组)
- SPOJ705-New Distinct Substrings-后缀数组
- [spoj694&spoj705]New Distinct Substrings(后缀数组)
- spoj -705 New Distinct Substrings--后缀数组
- SPOJ694&&SPOJ705 DISUBSTR - Distinct Substrings && SUBST1 - New Distinct Substrings 后缀数组
- SPOJ-SUBST1 New Distinct Substrings(后缀数组)
- SPOJ 705 New DistinctSubstrings (后缀数组)
- New Distinct Substrings SPOJ - SUBST1 (后缀数组)
- SPOJ SUBST1 - New Distinct Substrings (后缀数组)
- [后缀数组]spoj694 Distinct Substrings/spoj705 New Distinct Substrings
- SPOJ SUBST1 New Distinct Substrings 后缀数组-子串个数
- SPOJ 705 New Distinct Substrings