verify/string/suffix-automaton/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-automaton.hpp"
int main (){
string s ;
cin >> s ;
SuffixAutomaton sa ( s );
cout << sa . distinct_substrings ();
}
#line 1 "verify/string/suffix-automaton/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-automaton.hpp"
/**
* Author: Teetat T.
* Date: 2024-06-14
* Description: Suffix Automaton.
*/
template < class STR >
struct SuffixAutomaton {
using T = typename STR :: value_type ;
struct Node {
map < T , int > nxt ;
int link , len ;
Node ( int link , int len ) : link ( link ), len ( len ){}
};
vector < Node > nodes ;
int last ;
SuffixAutomaton () : nodes { Node ( - 1 , 0 )}, last ( 0 ){}
SuffixAutomaton ( const STR & s ) : SuffixAutomaton (){
for ( auto c : s ) extend ( c );
}
int new_node ( int link , int len ){
nodes . emplace_back ( Node ( link , len ));
return ( int ) nodes . size () - 1 ;
}
void extend ( T c ){
int cur = new_node ( 0 , nodes [ last ]. len + 1 );
int p = last ;
while ( p !=- 1 &&! nodes [ p ]. nxt . count ( c )){
nodes [ p ]. nxt [ c ] = cur ;
p = nodes [ p ]. link ;
}
if ( p !=- 1 ){
int q = nodes [ p ]. nxt [ c ];
if ( nodes [ p ]. len + 1 == nodes [ q ]. len ){
nodes [ cur ]. link = q ;
} else {
int r = new_node ( nodes [ q ]. link , nodes [ p ]. len + 1 );
nodes [ r ]. nxt = nodes [ q ]. nxt ;
while ( p !=- 1 && nodes [ p ]. nxt [ c ] == q ){
nodes [ p ]. nxt [ c ] = r ;
p = nodes [ p ]. link ;
}
nodes [ q ]. link = nodes [ cur ]. link = r ;
}
}
last = cur ;
}
ll distinct_substrings (){
ll res = 0 ;
for ( int i = 1 ; i < ( int ) nodes . size (); i ++ ) res += nodes [ i ]. len - nodes [ nodes [ i ]. link ]. len ;
return res ;
}
};
#line 4 "verify/string/suffix-automaton/number_of_substrings.test.cpp"
int main (){
string s ;
cin >> s ;
SuffixAutomaton sa ( s );
cout << sa . distinct_substrings ();
}
Back to top page