roychuang
我備課燒雞了 所以我要來偷
Trie
Trie
Trie
vector<array<int, 26>> trie(MAXN, array<int, 26> {});
vector<bool> is_end(MAXN, false);
int it = 1;Code
void insert(string &s) {
int cur = 0;
for (char c : s) {
if (trie[cur][c-'a'] == 0) {
trie[cur][c-'a'] = it++;
}
cur = trie[cur][c-'a'];
}
is_end[cur] = true;
}void dfs(int cur) {
for (int i = 0; i < 26; i++) if (trie[cur][i] != 0) {
dfs(trie[cur][i]);
}
// Example
cout << cur << endl;
}Trie
Problems
Hash
Hash
Hash
Code
using lli = long long int;
lli fpow(lli a, lli p, lli m) {
lli res = 1;
while (p) {
if (p & 1) res = (res * a) % m;
a = (a * a) % m;
p >>= 1;
}
return res;
}
lli inv(lli a, lli p) {
return fpow(a, p-2, p);
}
const lli hash_mod = 998244353;
const lli hash_mul = 257;
struct HashString {
int N;
vector<lli> h; // h[i] = hash([0...i])
HashString(string S) : N(SZ(S)), h(N) {
lli pre_mul = 1, last_hash = 0;
for (int i = 0; i < N; i++) {
h[i] = (last_hash + S[i] * pre_mul) % hash_mod;
pre_mul = (pre_mul * hash_mul) % hash_mod;
last_hash = h[i];
}
}
lli all() {
return h[N-1];
}
lli get_hash(int l, int r) {
if (l == 0) return h[r];
lli hash = h[r];
if (hash > h[l-1]) hash -= h[l-1];
else hash = hash + hash_mod - h[l-1];
lli div_inv = inv(fpow(hash_mul, l, hash_mod), hash_mod);
hash = (hash * div_inv) % hash_mod;
return hash;
}
};Hash
Problems
KMP
Knuth–Morris–Pratt
KMP
KMP
Code
vector<int> KMP(string s) {
int N = SZ(s);
vector<int> pi(N);
pi[0] = 0;
for (int i = 1; i < N; i++) {
int j = pi[i - 1];
while (j > 0 and s[i] != s[j]) j = pi[j - 1];
if (s[i] == s[j]) j++;
pi[i] = j;
}
return pi;
}KMP
Problems
Z
Z
Z
Code
vector<int> z_function(string s) {
int N = SZ(s);
vector<int> z(N);
z[0] = 0;
int L = 0, R = 0;
for (int i = 1; i < N; i++) {
if (i <= R and z[i - L] < R - i + 1) {
z[i] = z[i - L];
} else {
z[i] = max(0, R - i + 1);
while (i + z[i] < N and s[ z[i] ] == s[ i + z[i] ]) {
z[i]++;
}
if (i + z[i] - 1 > R) {
L = i;
R = i + z[i] - 1;
}
}
}
return z;
}Z
Problems
KMP <=> Z
KMP <=> Z
Z -> KMP
for (int i = 1; i < n; i++) {
if (z[i] > 0) F[i + z[i] - 1] = max(F[i + z[i] - 1], z[i]);
}
for (int i = n - 2; i >= 0; i--) {
F[i] = max(F[i + 1] - 1, F[i]);
}KMP <=> Z
for (int i = 1; i < n; i++) {
if (F[i] > 0) z[i - F[i] + 1] = max(z[i - F[i] + 1], F[i]);
}
for (int i = 1; i < n;) {
int j = 1, val;
while (j < z[i]) {
val = min(z[j], z[i] - j);
if (val < z[i + j]) {
break;
}
z[i + j] = val;
j++;
}
i += j;
}Manacher
Manacher
Code
vector<int> manacher(string &s) {
int N = SZ(s);
vector<int> m(N);
m[0] = 0;
int L = 0, R = 0;
for (int i = 1; i < N; i++) {
if (i <= R and m[L + L - i] < R - i) {
m[i] = m[L + L - i];
} else {
m[i] = max(0, R - i);
while (m[i] < i and i + m[i] + 1 < N and s[i + m[i] + 1] == s[i - m[i] - 1]) {
m[i]++;
}
if (i + m[i] > R) {
L = i;
R = i + m[i];
}
}
}
return m;
}Manacher
Manacher
Problems
AC Automaton
Aho-Corasick
AC Automaton
Code
struct Aho_Corasick {
vector<vector<int>> trie;
vector<int> fail;
vector<bool> is_end;
vector<int> str_to_id;
vector<vector<int>> dfs_adj;
vector<int> dp;
int it; // point to the end of the trie
Aho_Corasick(int MAXN) :
trie(MAXN, vector<int> (26, -1)),
fail(MAXN, 0),
is_end(MAXN, 0),
str_to_id(MAXN),
dfs_adj(MAXN),
dp(MAXN, 0),
it(0)
{}
void insert(string &t, int str_id) { // build trie
int cur = 0;
for (const char c : t) {
int j = c - 'a';
if (trie[cur][j] == -1) {
trie[cur][j] = ++it;
}
cur = trie[cur][j];
}
is_end[cur] = 1;
str_to_id[str_id] = cur;
}
void bfs() {
queue<int> qu;
for (int j = 0; j < 26; j++) {
if (trie[0][j] != -1) {
qu.push(trie[0][j]);
dfs_adj[0].eb(trie[0][j]);
} else {
trie[0][j] = 0; // fail edge
}
}
while (not qu.empty()) {
int cur = qu.front(); qu.pop();
for (int j = 0; j < 26; j++) {
int &nxt = trie[cur][j];
if (nxt != -1) {
int link_to = trie[fail[cur]][j];
fail[nxt] = link_to;
dfs_adj[link_to].eb(nxt);
qu.push(nxt);
} else {
nxt = trie[fail[cur]][j];
}
}
}
}
void dfs(int cur) {
for (const int &nxt : dfs_adj[cur]) {
dfs(nxt);
dp[cur] += dp[nxt];
}
}
void traverse(string &t) {
int cur = 0;
for (const char &c : t) {
cur = trie[cur][c-'a'];
dp[cur]++;
}
}
};AC Automaton
Problems
AC Automaton