不修改m有90就离谱
查看原帖
不修改m有90就离谱
157598
Magallan_forever楼主2020/7/21 15:20
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
char s[1000001];
int n,sa[1000001],rank_[1000001],h[1000001];
int cnt[1000001],sb[1000001],rank2[1000001];
void init_sa(){
	int i,j,k='z'+1,m,*rko=rank_,*rkn=rank2;
	n=strlen(s+1);
	for(i=1;i<=n;++i) ++cnt[s[i]+1];
	for(i=1;i<=k;++i) cnt[i]+=cnt[i-1];
	for(i=n;i>=1;--i) sa[cnt[s[i]+1]--]=i;
	for(i=1;i<=k;++i) cnt[i]=0;
	for(i=1,k=0;i<=n;++i) rank_[sa[i]]=(k+=(s[sa[i]]!=s[sa[i-1]]));
	for(m=1;m<n&&k<n;++i){//就这里,没修改m居然有90,写成m<<=1就AC了
		for(j=1;j<=m;++j) sb[j]=n-m+j;
		for(i=1;i<=n;++i) if(sa[i]>m) sb[j++]=sa[i]-m;
		for(i=1;i<=n;++i) ++cnt[rko[i]];
		for(i=1;i<=k;++i) cnt[i]+=cnt[i-1];
		for(i=n;i>=1;--i) sa[cnt[rko[sb[i]]]--]=sb[i];
		for(i=1;i<=k;++i) cnt[i]=0;
		for(i=1,k=0;i<=n;++i) rkn[sa[i]]=(k+=(rko[sa[i]]!=rko[sa[i-1]]||rko[sa[i]+m]!=rko[sa[i-1]+m]));
		swap(rko,rkn);
	}
	if(rko!=rank_) swap(rank_,rank2);
}
int main(){
	scanf("%s",s+1),init_sa();
	for(int i=1;i<=n;++i) printf("%d ",sa[i]);
	return 0;
}
2020/7/21 15:20
加载中...