This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub ttamx/cp-library
#define PROBLEM "https://judge.yosupo.jp/problem/number_of_substrings" #include "template.hpp" #include "string/suffix-automaton.hpp" int main(){ string s; cin >> s; SuffixAutomaton sa(s); cout << sa.distinct_substrings(); }
#line 1 "verify/yosupo/string/number_of_substrings.test.cpp" #define PROBLEM "https://judge.yosupo.jp/problem/number_of_substrings" #line 1 "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=INT_MAX/2; const int MOD=998244353; const int MOD2=1000000007; const ll LINF=LLONG_MAX/2; 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>; template<class T> using ordered_multiset = tree<T,null_type,less_equal<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 "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/yosupo/string/number_of_substrings.test.cpp" int main(){ string s; cin >> s; SuffixAutomaton sa(s); cout << sa.distinct_substrings(); }