【笔记】后缀数组
后缀数组 (SA)
0 约定
字符串下标从
字符串
「后缀
1 定义
这个字符串的所有非空后缀按字典序(用 ASCII 数值比较)从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。
后缀数组,
排名数组,
显然,这两个数组满足
2 求解
2.1 思想
先谈更 Native 的倍增。她较线性的 DC3 优势在于实现容易,常数小,空间复杂度小,而时间复杂度也只多一个
字典序总是具有可以贪心的性质,从贪心入手,类比 ST 表,我们另记
然后,我们枚举
2.2 实现
2.2.1 易错
- 注意
的右端点是很可能超过 的,但是因为 后面都是\0
,比所有的小写字母都小,所以没有影响。如果多测就要注意了。
2.2.2 过程
- 首先对
2.3 Code
/*
* Time Spent:
* Solution:
Tag:
* Summary:
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
char s[N];
int n, sa[N], rk[N], w[N], sw[N], x[N], y[N];
int main () {
#ifdef LOCAL
freopen("_1.in", "r", stdin);
freopen("_1.out", "w", stdout);
#else
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#endif
cin >> s+1, n = strlen(s+1);
int m = max(n, 1000);
for (int i = 1; i <= n; i++) w[s[i]]++;
for (int i = 1; i <= m; i++) sw[i] = sw[i-1] + w[i];
for (int i = 1; i <= n; i++) x[sw[s[i]]--] = i;
for (int i = 1; i <= n; i++)
rk[x[i]] = rk[x[i-1]] + !(s[x[i]] == s[x[i-1]]);
for (int j = 1; j <= n; j <<= 1) {
memset(w, 0, sizeof w);
for (int i = 1; i <= n; i++) w[rk[i+j]]++;
sw[0] = w[0];
for (int i = 1; i <= m; i++) sw[i] = sw[i-1] + w[i];
for (int i = 1; i <= n; i++) x[sw[rk[i+j]]--] = i;
memset(w, 0, sizeof w);
for (int i = 1; i <= n; i++) w[rk[i]]++;
for (int i = 1; i <= m; i++) sw[i] = sw[i-1] + w[i];
for (int i = n; i; i--)
y[sw[rk[x[i]]]--] = x[i];
static int r[N];
memset(r, 0, sizeof r);
for (int i = 1; i <= n; i++)
r[y[i]] = r[y[i-1]] + !(rk[y[i]] == rk[y[i-1]] && rk[y[i]+j] == rk[y[i-1]+j]);
memcpy(rk, r, sizeof r);
}
for (int i = 1; i <= n; i++) sa[rk[i]] = i;
for (int i = 1; i <= n; i++) cout << sa[i] << ' ';
return 0;
}
/*
g++ _1.cpp -o _1 -O2 -std=c++14 -DLOCAL; ./_1.exe
*/
对于一个子串,出现它的后缀的排名是一段连续的区间。可以二分左右边界求得。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· 深度对比:PostgreSQL 和 SQL Server 在统计信息维护中的关键差异