Distinct Substrings SPOJ - DISUBSTR suffix array

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.

 

 

A solution,
All sub-strings can be obtained by the prefix of a suffix
then the problem is transformed into all suffixes are not the same prefix a total number of
Start with a suffix suffix (sa [i]) can be produced n-sa [i] +1 prefix
but there are repeated, the number of repetition is the height [i]
all of the unique prefix n-sa [i] + 1- height [i]
Note that the suffix number is not 0 and the suffix -1 Comparative resolution (resolution because there is no suffix -1)
so the final answer will lead to fewer computing
The approach taken here is to add a string behind this has not been seen character
string length of solving this new
 
 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 }

 

 
Solution II.
First call out a substring total number, i.e., (n + 1) * n / 2 th, and then the value of height of the array is the number of the same prefix, suffix string so that less all of the total number of
height is formed Results
Because my code adds a character string on the basis of the original, so the No. 0 suffix is ​​not the original string, so the for loop from 2 to n
 
 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 }

 

 

Guess you like

Origin www.cnblogs.com/kongbursi-2292702937/p/12322405.html