第一问 SA 做法求调
查看原帖
第一问 SA 做法求调
1109707
godmoo楼主2024/3/5 18:14
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5;
typedef long long ll;
int t,n,m=128,c='z',sa[N],id[N],rk[N],tmp[N],cnt[N],rkid[N],hgt[N],s[N];
ll ans;
char str[N];
void radixsort(int w){
	int cur=0;
	for(int i=n;i>n-w;i--) id[++cur]=i;
	for(int i=1;i<=n;i++) if(sa[i]>w) id[++cur]=sa[i]-w;
	for(int i=1;i<=m;i++) cnt[i]=0;
	for(int i=1;i<=n;i++) cnt[rkid[i]=rk[id[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];
}
void getsa(){
	for(int i=1;i<=n;i++) cnt[rk[i]=s[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,p=0;w<n;w<<=1,m=p,p=0){
		radixsort(w);
		memcpy(tmp,rk,sizeof rk);
		for(int i=1;i<=n;i++){
			rk[sa[i]]=(tmp[sa[i-1]]==tmp[sa[i]]&&tmp[sa[i-1]+w]==tmp[sa[i]+w])?p:++p;
		}
		if(p==n) break;
	}
}
void getheight(){
	for(int i=1,k=0;i<=n;i++){
		if(rk[i]==1) continue; 
		if(k) k--;
		while(s[i+k]==s[sa[rk[i]-1]+k]) k++;
		hgt[rk[i]]=k;
	}
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%s",str+1);
		int len=strlen(str+1);
		ans+=(ll)len*(len+1)/2;
		for(int j=1;j<=len;j++) s[++n]=str[j];
		s[++n]=++c;
	}
	getsa(),getheight();
	for(int i=1;i<=n;i++) ans-=hgt[i];
	printf("%lld",ans);
	return 0;
}
2024/3/5 18:14
加载中...