后缀数组学习笔记

写在前面

学了5,6遍,学一次忘一次 所以还是整理一下吧

定义

一个rk数组 一个sa数组

rk[i]表示第i个后缀的排名

sa[i]表示排名为i的后缀的初始位置的下标

Code

#include<bits/stdc++.h>
using namespace std;
#define rint register int
const int maxn = 1e6 + 10;
int rk[maxn],tp[maxn],sa[maxn],cnt[maxn],n,m;
char s[maxn];

void Rsort() {
	memset(cnt+1,0,m*4);
	for(rint i = 1;i <= n;++i) cnt[rk[i]]++;
	for(rint i = 2;i <= m;++i) cnt[i] += cnt[i-1];
	for(rint i = n;i >= 1;--i) sa[cnt[rk[tp[i]]]--] = tp[i];
}

int main(){
	scanf("%s",s+1);
	n = strlen(s+1), m = 75;
	for(rint i = 1;i <= n;++i) rk[i] = s[i] - '0' + 1, tp[i] = i;
	Rsort();
	for(rint w = 1, p = 0;p < n;m = p, w *= 2) {
		p = 0;
		for(rint i = n-w+1;i <= n;++i) tp[++p] = i;
		for(rint i = 1;i <= n;++i) if(sa[i] > w) tp[++p] = sa[i] - w;
		Rsort(); memcpy(tp+1,rk+1,n*4); p = rk[sa[1]] = 1;
		for(rint i = 2;i <= n;++i) rk[sa[i]] = (tp[sa[i]]==tp[sa[i-1]] && tp[sa[i]+w]==tp[sa[i-1]+w]) ? p : ++p;
	}
	for(rint i = 1;i <= n;++i) printf("%d ",sa[i]);
	return 0;
}
posted @ 2021-01-27 21:34  HISKrrr  阅读(129)  评论(12编辑  收藏  举报