| 1 | // TODO: Add longest common subsring |
| 2 | const int MAXL = 100000; |
| 3 | struct 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){ |
nothing calls this directly
no outgoing calls
no test coverage detected