verify/string/suffix-array/number_of_substrings.test.cpp
Depends on
Code
#define PROBLEM "https://judge.yosupo.jp/problem/number_of_substrings"
#include "src/contest/template.hpp"
#include "src/string/suffix-array.hpp"
int main (){
string s ;
cin >> s ;
SuffixArray sa ( s );
int n = ( int ) s . size ();
cout << 1LL * n * ( n + 1 ) / 2 - accumulate ( sa . lcp . begin (), sa . lcp . end (), 0LL );
}
#line 1 "verify/string/suffix-array/number_of_substrings.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/number_of_substrings"
#line 2 "src/contest/template.hpp"
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std ;
using namespace __gnu_pbds ;
using ll = long long ;
using db = long double ;
using vi = vector < int > ;
using vl = vector < ll > ;
using vd = vector < db > ;
using pii = pair < int , int > ;
using pll = pair < ll , ll > ;
using pdd = pair < db , db > ;
const int INF = 0x3fffffff ;
const ll LINF = 0x1fffffffffffffff ;
const db DINF = numeric_limits < db >:: infinity ();
const db EPS = 1e-9 ;
const db PI = acos ( db ( - 1 ));
template < class T >
using ordered_set = tree < T , null_type , less < T > , rb_tree_tag , tree_order_statistics_node_update > ;
mt19937 rng ( chrono :: steady_clock :: now (). time_since_epoch (). count ());
mt19937_64 rng64 ( chrono :: steady_clock :: now (). time_since_epoch (). count ());
#line 2 "src/string/suffix-array.hpp"
/**
* Author: Teetat T.
* Date: 2024-06-14
* Description: Suffix Array.
*/
template < class STR >
struct SuffixArray {
int n ;
vector < int > sa , isa , lcp ;
// SparseTable<MinMonoid<int>> st;
SuffixArray (){}
SuffixArray ( const STR & s ){ init ( s );}
void init ( const STR & s ){
n = ( int ) s . size ();
sa = isa = lcp = vector < int > ( n + 1 );
sa [ 0 ] = n ;
iota ( sa . begin () + 1 , sa . end (), 0 );
sort ( sa . begin () + 1 , sa . end (),[ & ]( int i , int j ){ return s [ i ] < s [ j ];});
for ( int i = 1 ; i <= n ; i ++ ){
int x = sa [ i - 1 ], y = sa [ i ];
isa [ y ] = i > 1 && s [ x ] == s [ y ] ? isa [ x ] : i ;
}
for ( int len = 1 ; len <= n ; len <<= 1 ){
vector < int > ps ( sa ), pi ( isa ), pos ( n + 1 );
iota ( pos . begin (), pos . end (), 0 );
for ( auto i : ps ) if (( i -= len ) >= 0 ) sa [ pos [ isa [ i ]] ++ ] = i ;
for ( int i = 1 ; i <= n ; i ++ ){
int x = sa [ i - 1 ], y = sa [ i ];
isa [ y ] = pi [ x ] == pi [ y ] && pi [ x + len ] == pi [ y + len ] ? isa [ x ] : i ;
}
}
for ( int i = 0 , k = 0 ; i < n ; i ++ ){
for ( int j = sa [ isa [ i ] - 1 ]; j + k < n && s [ j + k ] == s [ i + k ]; k ++ );
lcp [ isa [ i ]] = k ;
if ( k ) k -- ;
}
// st.init(lcp);
}
// int get_lcp(int i,int j){
// if(i==j)return n-i;
// auto [l,r]=minmax(isa[i],isa[j]);
// return st.query(l+1,r);
// }
};
#line 4 "verify/string/suffix-array/number_of_substrings.test.cpp"
int main (){
string s ;
cin >> s ;
SuffixArray sa ( s );
int n = ( int ) s . size ();
cout << 1LL * n * ( n + 1 ) / 2 - accumulate ( sa . lcp . begin (), sa . lcp . end (), 0LL );
}
Back to top page