记录编号 566818 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 后缀数组 最终得分 100
用户昵称 Gravataryrtiop 是否通过 通过
代码语言 C++ 运行时间 2.542 s
提交时间 2021-11-16 22:31:31 内存使用 8.43 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 300005;
char s[maxn];
int rk[maxn],sa[maxn],height[maxn],y[maxn],p,n,m,cnt[maxn];
int main() {
	freopen("sav.in","r",stdin);
	freopen("sav.out","w",stdout);
	scanf("%s",s + 1);
	n = strlen(s + 1);
	m = 300;
	for(int i = 1;i <= n;++ i)++ cnt[rk[i] = s[i]];
	for(int i = 2;i <= m;++ i)cnt[i] += cnt[i - 1];
	for(int i = n;i >= 1;-- i)sa[cnt[rk[i]] --] = i;
	for(int k = 1;k <= n;k <<= 1,m = p) {
		p = 0;
		for(int i = n - k + 1;i <= n;++ i) {
			y[++ p] = i;
		}
		for(int i = 1;i <= n;++ i) {
			if(sa[i] > k) {
				y[++ p] = sa[i] - k;
			}
		}
		for(int i = 1;i <= m;++ i)cnt[i] = 0;
		for(int i = 1;i <= n;++ i)++ cnt[rk[i]];
		for(int i = 2;i <= m;++ i)cnt[i] += cnt[i - 1];
		for(int i = n;i >= 1;-- i)sa[cnt[rk[y[i]]] --] = y[i],y[i] = 0;
		swap(rk , y);
		rk[sa[1]] = 1;
		p = 1;
		for(int i = 2;i <= n;++ i)rk[sa[i]] = y[sa[i]] == y[sa[i - 1]]&&y[sa[i] + k] == y[sa[i - 1] + k] ? p : ++ p;
		if(p >= n)break ;
	} 
	for(int i = 1;i <= n;++ i)rk[sa[i]] = i;
	int j,k = 0;
	for(int i = 1;i <= n;++ i) {
		if(rk[i] == 1)continue ;
		if(k)-- k;
		j = sa[rk[i] - 1];
		while(s[i + k] == s[j + k]&&i + k <= n&&j + k <= n)++ k;
		height[rk[i]] = k;
	}
	for(int i = 1;i <= n;++ i) {
		printf("%d ",sa[i] - 1);
	}
	putchar('\n');
	for(int i = 1;i <= n;++ i) {
		printf("%d ",height[i]);
	}
	fclose(stdin);
	fclose(stdout);
	return 0; 
}