Skip to content

Commit a54de24

Browse files
committed
2 parents 4e39706 + 79bf24c commit a54de24

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
class SuffixAutomata {
2+
3+
#define charToInt(ch) (ch-'a')
4+
5+
struct state {
6+
int len, link;
7+
int next[26];
8+
int firstPos;
9+
bool isClone;
10+
vector<int> backLink;
11+
12+
bool has ( char ch ) {
13+
return next[ charToInt(ch) ] != -1;
14+
}
15+
};
16+
17+
int sz, last;
18+
vector< state > Pool;
19+
20+
void getAllOccurrence ( int v , int P_length , vector<int> &ret ) {
21+
if ( !Pool[v].isClone ) ret.pb( Pool[v].firstPos - P_length + 1 );
22+
for ( size_t i = 0; i < Pool[v].backLink.size(); i++ )
23+
getAllOccurrence ( Pool[v].backLink[i] , P_length , ret);
24+
}
25+
26+
public :
27+
28+
SuffixAutomata( int maxlength ) {
29+
Pool = vector<state> ( maxlength * 2 );
30+
}
31+
32+
void initialize() {
33+
rep( i , sz ) Pool[i].backLink.clr, Pool[i].isClone = false, Pool[i].link = -1, Pool[i].len = 0;
34+
sz = last = 0;
35+
Pool[0].len = 0;
36+
Pool[0].link = -1;
37+
mem( Pool[sz].next , -1 );
38+
++sz;
39+
}
40+
41+
void addChar ( char c ) {
42+
int cur = sz++;
43+
mem( Pool[cur].next , -1 );
44+
Pool[cur].len = Pool[last].len + 1;
45+
Pool[cur].firstPos = Pool[cur].len - 1;
46+
Pool[cur].isClone = false;
47+
int p;
48+
for ( p = last; p != -1 && !Pool[p].has(c) ; p = Pool[p].link ) Pool[p].next[ charToInt(c) ] = cur;
49+
if ( p == -1 ) Pool[cur].link = 0;
50+
else {
51+
int q = Pool[p].next[ charToInt(c) ];
52+
if ( Pool[p].len + 1 == Pool[q].len ) Pool[cur].link = q;
53+
else {
54+
int clone = sz++;
55+
mem( Pool[clone].next , -1 );
56+
Pool[clone].len = Pool[p].len + 1;
57+
Pool[clone].firstPos = Pool[p].firstPos;
58+
Pool[clone].isClone = true;
59+
memcpy( Pool[clone].next , Pool[q].next , sizeof (Pool[q].next) );
60+
Pool[clone].link = Pool[q].link;
61+
for ( ; p != -1 && Pool[p].next[charToInt(c)] == q; p = Pool[p].link )
62+
Pool[p].next[ charToInt(c) ] = clone;
63+
Pool[q].link = Pool[cur].link = clone;
64+
}
65+
}
66+
last = cur;
67+
}
68+
69+
void construct ( string &str ) {
70+
rep( i , sz(str) ) addChar(str[i]);
71+
for( int v=1; v<sz; v++ ) {
72+
if( Pool[v].link != -1 )
73+
Pool[ Pool[v].link ].backLink.pb( v );
74+
}
75+
}
76+
77+
int findState ( string &pattern ) {
78+
int now = 0, length = 0;
79+
rep( i , sz( pattern ) ) {
80+
char ch = pattern[i];
81+
while( now && !Pool[now].has( ch ) ) {
82+
now = Pool[now].link;
83+
length = Pool[now].len;
84+
}
85+
if( Pool[now].has(ch) ){
86+
now = Pool[now].next[ch-'a'];
87+
length++;
88+
}
89+
}
90+
return ( length == sz(pattern) ? now : -1 );
91+
}
92+
93+
vector<int> getAllOccurrence ( string &pattern ) {
94+
vector<int> ret;
95+
int v = findState( pattern );
96+
if( v == -1 ) return ret;
97+
getAllOccurrence( v , sz(pattern) , ret );
98+
sort ( all ( ret ) );
99+
return ret;
100+
}
101+
102+
#undef charToInt
103+
};

0 commit comments

Comments
 (0)