后缀数组WA求调
查看原帖
后缀数组WA求调
763878
Jerry_heng楼主2024/3/27 16:52
#include<bits/stdc++.h>
using namespace std;
const int mxn=4e6+10;
int n,kk,s[mxn],m,rk[mxn],id[mxn],sa[mxn],height[mxn],oldrk[mxn],rkid[mxn],cnt[mxn],q[mxn];
bool cmp(int x,int y,int w){
	return oldrk[x]==oldrk[y]&&oldrk[x+w]==oldrk[y+w];
}
int main(){
	scanf("%d%d",&n,&kk);
	for(int i=1;i<=n;i++)scanf("%d",&s[i]);
	m=1000000;
	for(int i=1;i<=n;i++)rk[i]=s[i],cnt[rk[i]]++;
	for(int i=1;i<=m;i++)cnt[i]+=cnt[i-1];
	for(int i=n;i>=1;i--)sa[cnt[rk[i]]--]=i;
	for(int w=1;w<n;w<<=1){
		int p=0;
		for(int i=n;i>n-w;i--)id[++p]=i;
		for(int i=1;i<=n;i++)
			if(sa[i]>w)id[++p]=sa[i]-w;
		memset(cnt,0,sizeof cnt);
		for(int i=1;i<=n;i++)rkid[i]=rk[id[i]],cnt[rkid[i]]++;
		for(int i=1;i<=m;i++)cnt[i]+=cnt[i-1];
		for(int i=n;i>=1;i--)sa[cnt[rkid[i]]--]=id[i];
		swap(rk,oldrk);
		m=0;
		for(int i=1;i<=n;i++){
			m+=cmp(sa[i-1],sa[i],w)^1;
			rk[sa[i]]=m;
		}
	}
	for(int i=1,k=0;i<=n;i++){
		if(rk[i]==1)k=0;
		else{
			if(k>0)k--;
			int j=sa[rk[i]-1];
			while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k])k++;
		}
		height[rk[i]]=k;
	}
	int head=1,tail=0,ans=0;
	for(int i=2;i<=n;i++){
		while(head<=tail&&q[head]<=i-kk+1)head++;
		if(tail>=head&&height[i]<=height[q[tail]])tail--;
		q[++tail]=i;
		if(i>=kk)ans=max(ans,height[q[head]]);
	}
	printf("%d\n",ans);
	return 0;
}
2024/3/27 16:52
加载中...