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
原创粉丝点击