比赛 清华集训2017模板练习 评测结果 AAAAAAAAAA
题目名称 后缀排序 最终得分 100
用户昵称 Cydiater 运行时间 1.655 s
代码语言 C++ 内存使用 18.31 MiB
提交时间 2017-07-17 14:29:41
显示代码纯文本
//SA
//by Cydiater
//2017.7.17
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define up(i,j,n)	for(int i=j;i<=n;i++)
#define down(i,j,n)	for(int i=j;i>=n;i--)
#define cmax(a,b)	a=max(a,b)
#define cmin(a,b)	a=min(a,b)
#define FILE		"sais"

const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;

int N;
char s[MAXN];

namespace SA{
	int sa[MAXN],rnk[MAXN],tmp[MAXN],cnt[MAXN],p[MAXN];
	inline bool equ(int x,int y,int l){return rnk[x]==rnk[y]&&rnk[x+l]==rnk[y+l];}
	void Build(){
		scanf("%s",s+1);
		N=strlen(s+1);
		up(i,1,N){
			sa[i]=i;
			rnk[i]=s[i];
		}
		for(int l=0,pos,sig=300;pos<N;sig=pos){
			pos=0;
			up(i,N-l+1,N)p[++pos]=i;
			up(i,1,N)if(sa[i]>l)p[++pos]=sa[i]-l;
			up(i,0,sig)cnt[i]=0;
			up(i,1,N)cnt[rnk[i]]++;
			up(i,1,sig)cnt[i]+=cnt[i-1];
			down(i,N,1)sa[cnt[rnk[p[i]]]--]=p[i];
			pos=0;
			up(i,1,N)tmp[sa[i]]=equ(sa[i],sa[i-1],l)?pos:++pos;
			up(i,1,N)rnk[i]=tmp[i];
			l=!l?1:(l<<1);
		}
	}
}using namespace SA;

int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	SA:Build();
	up(i,1,N)printf("%d ",sa[i]-1);
	puts("");
	return 0;
}