trie(這個算資料結構嗎)
// 原題為16進位制trie,將就看看吧)
string a[N];
int to[N * 22][18], x[N * 22];
int cnt;
void add(int id) {
string s = a[id];
int cur = 0;
for(int i = 0; i <= 19; i++) {
int t;
if(s[i] >= '0' && s[i] <= '9') {
t = s[i] - '0';
} else {
t = 10 + s[i] - 'A';
}
if(to[cur][t] == 0) to[cur][t] = ++cnt;
cur = to[cur][t];
}
x[cur] = id;
}
int query(string &s) {
int cur = 0;
for(int i = 19; i >= 0; i--) {
int t;
if(s[i] >= '0' && s[i] <= '9') {
t = s[i] - '0';
} else {
t = 10 + s[i] - 'A';
}
int val = -1, ans = 0;
for(int r = 0; r < 16; r++) {
if(to[cur][r] && (t + r) % 16 > val) {
val = (t + r) % 16;
ans = r;
}
}
cur = to[cur][ans];
}
return x[cur];
}
KMP
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
int n, m;
char s1[N], s2[N];
int f[N], l[N];
void getfail() {
for(int i = 2, j = 0; i <= m; i++) {
while (j && s2[i] != s2[j + 1]) j = f[j];
if (s2[j + 1] == s2[i]) j ++;
f[i] = j;
}
}
int main() {
scanf("%s%s", s1 + 1, s2 + 1);
n = strlen(s1 + 1), m = strlen(s2 + 1);
getfail();
for(int i = 1, j = 0; i <= n; i++) {
while(j && (j == n || s1[i] != s2[j + 1])) j = f[j];
if(s1[i] == s2[j + 1]) j++;
l[i] = j;
if(l[i] == m) printf("%d\n", i - m + 1);
}
for(int i = 1; i <= m; i++) printf("%d ", f[i]);
system("pause");
return 0;
}