MCPcopy Create free account
hub / github.com/SuprDewd/CompetitiveProgramming / suffix_automaton

Class suffix_automaton

code/strings/suffix_automaton.cpp:3–62  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1// TODO: Add longest common subsring
2const int MAXL = 100000;
3struct suffix_automaton {
4 vi len, link, occur, cnt;
5 vector<map<char,int> > next;
6 vector<bool> isclone;
7 ll *occuratleast;
8 int sz, last;
9 string s;
10 suffix_automaton() : len(MAXL*2), link(MAXL*2),
11 occur(MAXL*2), next(MAXL*2), isclone(MAXL*2) { clear(); }
12 void clear() { sz = 1; last = len[0] = 0; link[0] = -1;
13 next[0].clear(); isclone[0] = false; }
14 bool issubstr(string other){
15 for(int i = 0, cur = 0; i < size(other); ++i){
16 if(cur == -1) return false; cur = next[cur][other[i]]; }
17 return true; }
18 void extend(char c){ int cur = sz++; len[cur] = len[last]+1;
19 next[cur].clear(); isclone[cur] = false; int p = last;
20 for(; p != -1 && !next[p].count(c); p = link[p])
21 next[p][c] = cur;
22 if(p == -1){ link[cur] = 0; }
23 else{ int q = next[p][c];
24 if(len[p] + 1 == len[q]){ link[cur] = q; }
25 else { int clone = sz++; isclone[clone] = true;
26 len[clone] = len[p] + 1;
27 link[clone] = link[q]; next[clone] = next[q];
28 for(; p != -1 && next[p].count(c) && next[p][c] == q;
29 p = link[p]){
30 next[p][c] = clone; }
31 link[q] = link[cur] = clone;
32 } } last = cur; }
33 void count(){
34 cnt=vi(sz, -1); stack<ii> S; S.push(ii(0,0));
35 map<char,int>::iterator i;
36 while(!S.empty()){
37 ii cur = S.top(); S.pop();
38 if(cur.second){
39 for(i = next[cur.first].begin();
40 i != next[cur.first].end();++i){
41 cnt[cur.first] += cnt[(*i).second]; } }
42 else if(cnt[cur.first] == -1){
43 cnt[cur.first] = 1; S.push(ii(cur.first, 1));
44 for(i = next[cur.first].begin();
45 i != next[cur.first].end();++i){
46 S.push(ii((*i).second, 0)); } } } }
47 string lexicok(ll k){
48 int st = 0; string res; map<char,int>::iterator i;
49 while(k){
50 for(i = next[st].begin(); i != next[st].end(); ++i){
51 if(k <= cnt[(*i).second]){ st = (*i).second;
52 res.push_back((*i).first); k--; break;
53 } else { k -= cnt[(*i).second]; } } }
54 return res; }
55 void countoccur(){
56 for(int i = 0; i < sz; ++i){ occur[i] = 1 - isclone[i]; }
57 vii states(sz);
58 for(int i = 0; i < sz; ++i){ states[i] = ii(len[i],i); }
59 sort(states.begin(), states.end());
60 for(int i = (int)size(states)-1; i >= 0; --i){

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected