这里贴板子, 近一周每天都要打截止那天早上已经会的。
知识笔记贴在:
LCP部分性质/证明 与后缀数组的 rk 数组与 height 数组
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 233;
char s1[N], s2[N];
int l_1, l_2;
int fil[N];
int main()
{
scanf("%s%s",s1+1,s2+1);
l_1 = strlen(s1+1), l_2 = strlen(s2+1);
fil[1]=0;
for(int i=2,j=0; i<=l_2; ++i) {
while(j && s2[j+1]!=s2[i]) j=fil[j];
if(s2[j+1] == s2[i]) ++j;
fil[i] = j;
}
for(int i=1,j=0; i<=l_1; ++i) {
while(j && (j==l_2 || s2[j+1]!=s1[i])) j=fil[j];
if(s2[j+1] == s1[i]) ++j;
if(j==l_2) cout << (i-l_2+1) << '
';
}
for(int i=1; i<=l_2; ++i) cout << fil[i] << ' ';
return 0;
}
AC 自动机板子
struct acam{
int tr[N][26], fil[N], fa[N], tot;
void ins(char *s, int n)
{
int x=0;
for(int i=0 i<n; ++i) {
char ch = s[i] - 'a';
if(!tr[x][ch]) {
int y = ++tot;
tr[x][ch] = y;
fa[y] = x;
}
x = tr[x][ch];
}
}
void get_fail()
{
queue<int>q;
for(int i=0; i<26; ++i)
if(tr[0][i]) q.push(tr[0][i]), fil[tr[0][i]] = 0;
while(!q.empty())
{
int x = q.front(); q.pop();
for(int i=0; i<26; ++i)
if(tr[x][i]) fil[tr[x][i]] = tr[fil[x]][i], q.push(tr[x][i]);
else tr[x][i] = tr[fil[x]][i];
}
}
} A;
倍增后缀排序
//nlogn倍增后缀排序
char s[MAXN];
int c[MAXN];
int x[MAXN];
int y[MAXN];
int sa[MAXN];
inline void get_sa(int n, int m) {
for(int i = 1; i <= n; ++i) ++c[x[i] = s[i]];
for(int i = 1; i <= m; ++i) c[i] += c[i-1];
for(int i = n; i >= 1; --i) sa[c[x[i]]--] = i;
for(int w = 1, q = 0; w < n; w <<= 1, q = 0) {
for(int i = n-k+1; i <= n; ++i) y[++q] = i;
for(int i = 1; i <= n; ++i) if(sa[i] > k) y[++q] = sa[i] - k;
for(int i = 1; i <= m; ++i) c[i] = 0;
for(int i = 1; i <= n; ++i) c[x[i]]++;
for(int i = 1; i <= m; ++i) c[i] += c[i-1];
for(int i = n; i >= 1; --i) sa[c[x[y[i]]]--] = y[i];
swap(x, y); x[sa[1]] = q = 1;
for(int i=2; i<=n; ++i)
x[sa[i]] = y[sa[i]] == y[sa[i-1]] && y[sa[i] + w] == y[sa[i-1] + w] ? q : ++q;
if(q == n) break;
m = q;
}
}
rk + height 数组
int rk[N], height[N];
inline void get_height() {
for(int i=1; i<=n; ++i) rk[sa[i]] = i;
for(int i=1, j, k=0; i<=n; ++i) {
if(rk[i]==1) continue;
j = sa[rk[i] - 1]; k -= k>0;
while(i+k<=n && j+k<=n && s[i+k]==s[j+k]) ++k;
height[rk[i]] = k;
}
}