Spoj-DISUBSTR - Distinct Substrings ~ New Distinct Substrings SPOJ - SUBST1 ~ (suffix array solving number substring)

Spoj-DISUBSTR - Distinct Substrings

New Distinct Substrings SPOJ - SUBST1

I was under the topic to the suffix array kuangbin

 

Like solving these two problems that Italy number of different string string:

This app is a basic suffix array

 

Given a string, the number of different request substring.

 

Algorithm Analysis: for each prefix substring must be a suffix, then the original problem is equivalent to finding the number is not the same among all prefixes suffixes.

If all Suffixes suffix (sa [1]), suffix (sa [2]), suffix (sa [3]), ......, sequence suffix (sa [n]) is calculated, not difficult to find,

Add to the mix for each new suffix suffix (sa [k]), it generates n-sa [k] +1 new prefix.

But there are height [k] is a character string and the prefix in front of the same.

Therefore suffix (sa [k]) the "contribution" to the n-sa [k] + [k] different substrings 1- height. (This also equivalent to the number of the same string len * (len + 1) / 2-)

Is the answer to the original question of post-accumulation. The time complexity of this approach is O (n).

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <set>
  7 #include <iostream>
  8 #include <map>
  9 #include <stack>
 10 #include <string>
 11 #include <time.h>
 12 #include <vector>
 13 #define  pi acos(-1.0)
 14 #define  eps 1e-9
 15 #define  fi first
 16 #define  se second
 17 #define  rtl   rt<<1
 18 #define  rtr   rt<<1|1
 19 #define  bug         printf("******\n")
 20 #define  mem(a,b)    memset(a,b,sizeof(a))
 21 #define  name2str(x) #x
 22 #define  fuck(x)     cout<<#x" = "<<x<<endl
 23 #define  f(a)        a*a
 24 #define  sf(n)       scanf("%d", &n)
 25 #define  sff(a,b)    scanf("%d %d", &a, &b)
 26 #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
 27 #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
 28 #define  pf          printf
 29 #define  FRE(i,a,b)  for(i = a; i <= b; i++)
 30 #define  FREE(i,a,b) for(i = a; i >= b; i--)
 31 #define  FRL(i,a,b)  for(i = a; i < b; i++)+
 32 #define  FRLL(i,a,b) for(i = a; i > b; i--)
 33 #define  FIN         freopen("data.txt","r",stdin)
 34 #define  gcd(a,b)    __gcd(a,b)
 35 #define  lowbit(x)   x&-x
 36 #define rep(i,a,b) for(int i=a;i<b;++i)
 37 #define per(i,a,b) for(int i=a-1;i>=b;--i)
 38 
 39 using namespace std;
 40 typedef long long  LL;
 41 typedef unsigned long long ULL;
 42 const int maxn = 1e5 + 7;
 43 const int maxm = 8e6 + 10;
 44 const int INF = 0x3f3f3f3f;
 45 const int mod = 10007;
 46 
 47 //rnk从0开始
 48 //sa starting from 1, because the last character (minimum) at No. 0
 49  // height from the beginning, as represented by the sa [i - 1] and sa [I]
 50  // multiplication algorithm is O (nlogn) 
51 is  int WA [MAXN], WB [MAXN], WV [MAXN], WS_ [MAXN];
 52 is  int Rank [MAXN], height [MAXN], SA [MAXN], R & lt [MAXN];
 53 is  int n-, Maxx;
 54 is  char S [MAXN];
 55  // range function parameter m represents Suffix characters in the string, radix sorting is a parameter, if the original is a letter can be taken directly sequence 128, if the original sequence itself are integers , then m may take a value larger than the maximum integer of 1
 56  // be sorted string in array r from r [0] to r [n-1], a length of n-
 57 is  // for comparison size, may be added after a character string, the character does not appear in the preceding character, and the character to be smaller than the previous
 58  // supra, in order to facilitate the operation function, convention r [n-1] in addition to the outer All r [i] is greater than 0, r [n-1]
 = 059  // After the function, the result in array sa, sa from [0] to sa [. 1-n-] 
60  void Suffix ( int * R & lt, int * sa, int n-, int m) {
 61 is      int I, J , K, WA = X *, Y * = WB, * T;
 62 is      // length of string collation 1
 63      // in general, the title character string, the maximum value of r will not be great, so used herein, the radix sort
 64      // If the maximum value of r is large, then this code into quicksort 
65      for (I = 0 ; I <m; I ++) WS_ [I] = 0 ;
 66      for (I = 0 ; I <n-; I ++) WS_ [X [I] = R & lt [I]] ++; // count the number of characters 
67     for (i = . 1 ; i <m; i ++) WS_ [i] + = WS_ [i - . 1 ]; // count i is not greater than the number of characters in the character 
68      for (i = n-- . 1 ; i> = 0 ; Inc. (www.i-levelmedia.com)) SA [- WS_ [x [I]]] = I; // calculate rank character
 69      // radix sort
 70      // value x stored in the array corresponds to a rank value 
71 is      for (J = . 1 , = K . 1 ; K <n-; J * = 2 , m = K) {
 72          // J is the current length of the string, the result is stored in an array of y of the second sort key
 73          // second keyword ranking 
74          for (K = 0, = N-I - J; I <n-; I ++) Y [K ++] = I; // second keyword is 0 top surface 
75          for (I = 0 ; I <n-; I ++) IF (sa [i]> = j) Y [K ++] = sa [i] - j; // length j of the substring of sa [i] should be of length 2 * j of the substring of sa [i] - j of suffix (second key) as a 2 * j substrings of all sorted according to the length of a second key 
76          for (I = 0 ; I <n-; I ++) WV [I] = X [Y [ I]]; // extracting a first key
 77          // Sort the first key (on the same principle as the length of the string collation 1) 
78          for (I = 0 ; I <m; I ++) WS_ [I ] = 0 ;
 79          for (I = 0 ; I <n-; I ++) WS_ [WV [I]] ++ ;
 80          for(I = . 1 ; I <m; I ++) WS_ [I] + = WS_ [I - . 1 ];
 81          for (n-I = - . 1 ; I> = 0 ; Inc. (www.i-levelmedia.com)) SA [- WS_ [ WV [I]]] = Y [I]; // press a first key, to calculate the length of 2 * j substrings ranking
 82          // in this case the array x of length ranking of the j substrings , y array is still based on a result of the second sort key
 83          // calculate the length of ranking 2 * j of the substring, saved to the array X 
84          T = X;
 85          X = y;
 86          y = T;
 87          for (X [SA [ 0 ]] = 0 , I = K = . 1 ; I <n-; ++ I)
 88             X [SA [I]] = (Y [SA [I - . 1 ]] == Y [SA [I]] && Y [SA [I - . 1 ] + J] == Y [SA [I] + J] ?) K - . 1 : K ++ ;
 89          // If the length of 2 * j of the substring of sa [i] with the sa [i - 1] are identical, they have the same rank 
90      }
 91 is  }
 92  void calheight ( int * R & lt, int * SA, int n-) {
 93      int I, J, K = 0 ;
 94      for (I = . 1 ; I <= n-; I ++) Rank [SA [I]] = I;
 95      for (I = 0 ; I <n-; height [Rank [I ++]] = K)
 96         for ( k ? k-- : 0, j = sa[Rank[i] - 1]; r[i + k] == r[j + k]; k++ );
 97 }
 98 
 99 int main() {
100     int T;
101     sf ( T );
102     while ( T-- )  {
103         scanf ( "%s", s );
104         maxx = 0, n = strlen ( s );
105         for ( int i = 0; i < n ; i++ ) r[i] = ( int ) s[i], maxx = max ( maxx, r[i] );
106         r[n] = 0;
107 //        for ( int i = 0 ; i < n ; i++ ) printf ( "%d%c", r[i], ( i == n - 1 ? '\n' : ' ' ) );
108         Suffix ( r, sa, n + 1, maxx + 1 );
109         calheight ( r, sa, n );
110         LL ans = 0;
111         for ( int i = 1 ; i <= n ; i++ ) ans += 1LL * ( n - sa[i] - height[i] );
112         printf ( "%lld\n", ans );
113     }
114     return 0;
115 }
View Code

 

Guess you like

Origin www.cnblogs.com/qldabiaoge/p/11329914.html