SPOJ DISUBSTR Distinct Substrings
来源:互联网 发布:c语言中的头文件是 编辑:程序博客网 时间:2024/06/03 17:12
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.
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.
题意:求不重复的子串有多少个
思路 : 对于一个以第k个字符为起始位置的字符串 ,他能产生的前缀为len - k 个,但是有height[rank[k]] 个是重复的,所以要减去。这道题我使用DC3 写的,
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdlib.h>#include <algorithm>using namespace std;#define MAXN 1010*3#define F(x) ((x)/3 + ((x)%3 == 1 ? 0 : tb))#define G(x) ((x) < tb?(x)*3 + 1:((x) - tb)*3+2)int wa[MAXN], wb[MAXN], wv[MAXN], wss[MAXN];int c0(int *r, int a, int b){ return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2];}int c12(int k, int *r, int a, int b){ if(k == 2) return r[a] < r[b] || (r[a] == r[b] && c12(1, r, a + 1, b + 1)); else return r[a] < r[b] || (r[a] == r[b] && wv[a + 1] < wv[b + 1]);}void _sort(int *r, int *a, int *b, int n, int m){ int i; for( i = 0; i < n; i++) wv[i] = r[a[i]]; for( i = 0; i < m; i++) wss[i] = 0; for( i = 0; i < n; i++) wss[wv[i]]++; for( i = 1; i < m; i++) wss[i] += wss[i - 1]; for( i = n - 1; i >= 0; i--) b[--wss[wv[i]]] = a[i];}void dc3(int *r, int *sa, int n, int m){ int i, j, *rn = r + n; int *san = sa + n, ta = 0, tb = (n + 1)/3, tbc = 0, p; r[n] = r[n+1] = 0; for( i = 0; i < n; i++) if(i%3 != 0) wa[tbc++] = i; _sort(r + 2, wa, wb, tbc, m); _sort(r + 1, wb, wa, tbc, m); _sort(r, wa, wb, tbc, m); for( p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; i++) rn[F(wb[i])] = c0(r, wb[i - 1], wb[i])? p - 1 : p ++; if(p < tbc) dc3(rn, san, tbc, p); else for( i = 0; i < tbc; i++) san[rn[i]] = i; for( i = 0; i < tbc; i++) if(san[i] < tb) wb[ta++] = san[i] * 3; if(n % 3 == 1) wb[ta++] = n - 1; _sort(r, wb, wa, ta, m); for( i = 0; i < tbc; i++) wv[wb[i] = G(san[i])] = i; for( i = 0, j = 0, p = 0; i < ta && j < tbc; p ++) sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++]: wb[j++]; for( ; i < ta; p++) sa[p] = wa[i++]; for( ; j < tbc; p++) sa[p] = wb[j ++];}void da(int str[], int sa[], int _rank[], int height[], int n, int m){ for( int i = n; i < n*3; i++) str[i] = 0; dc3(str, sa, n + 1, m); int i, j, k = 0; for( i = 0; i <= n; i++) _rank[sa[i]] = i; for( i = 0; i < n; i++) { if(k) k --; j = sa[_rank[i] - 1]; while(str[i+k] == str[j+k]) k++; height[_rank[i]] = k; }}char s[MAXN];int str[MAXN], sa[MAXN], _rank[MAXN], height[MAXN];int n, m;int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s",&s); int len =strlen(s); for( int i = 0; i < len; i++) str[i] = s[i]; da(str, sa, _rank, height, len, 128); int ans = 0; for( int i = 1; i <= len; i++) ans += len - sa[i] - height[i]; printf("%d\n",ans); } return 0;}
0 0
- SPOJ DISUBSTR Distinct Substrings
- SPOJ DISUBSTR Distinct Substrings
- SPOJ - DISUBSTR Distinct Substrings
- SPOJ DISUBSTR Distinct Substrings
- SPOJ 694 DISUBSTR Distinct Substrings 后缀数组
- [SPOJ DISUBSTR]Distinct Substrings(后缀数组)
- SPOJ DISUBSTR Distinct Substrings (后缀数组)
- 【SPOJ-DISUBSTR】Distinct Substrings【后缀数组】
- 【SPOJ DISUBSTR】Distinct Substrings 后缀数组
- SPOJ DISUBSTR Distinct Substrings(后缀数组)
- SPOJ DISUBSTR Distinct Substrings 后缀数组子串个数
- spoj 694 DISUBSTR - Distinct Substrings (后缀数组)
- SPOJ DISUBSTR - Distinct Substrings or SUBST1 - New Distinct Substrings 【不同子串数目】
- SPOJ 694 / SPOJ DISUBSTR Distinct Substrings【后缀数组】不相同的子串的个数
- SPOJ - DISUBSTR Distinct Substrings(后缀数组求不相同的子串个数)
- SPOJ DISUBSTR - Distinct Substrings(后缀数组[不相同的子串的个数])
- SPOJ 694 Distinct Substrings
- 694. Distinct Substrings SPOJ
- 邮票分你一半
- 二叉排序树与平衡二叉排序树的转化
- HDU5242(树DP)
- 重学C++Primer笔记6---指针、typedef、const、define彻底理解
- [sicily]1154. Easy sort
- SPOJ DISUBSTR Distinct Substrings
- hadoop远程调试
- gns3 1.4 使用gns3vm,新的iourc
- 软件测试管理体系
- hdu--2955
- ARM专业术语1
- 敏捷测试与传统测试的区别
- SGU 347 Join the Strings 字符串 排序 思维
- 树莓派设置无线热点(RTL8188CUS芯片)