求助:后缀自动机P3804只A了第一个点
查看原帖
求助:后缀自动机P3804只A了第一个点
693923
hejiale楼主2024/3/25 08:31

求助:后缀自动机P3804只A了第一个点

#include<iostream>
using namespace std;
struct tree{
	int next[26];//转移 
	long long lick;//后缀链接 
	long long len;//长度 
	long long cut;//数量 
	long long nexty;
}SAM[4500000];//SAM
string s;
long long last,a,cnt=1,ans,head[450000];
void node(int x){
	SAM[head[SAM[x].len]].nexty =x;
	head[SAM[x].len]=x;
}
void add(){
	int cur=cnt++;
	char c=s[a];
	SAM[cur].len=SAM[last].len+1;
	node(cur);
	SAM[cur].cut=1;
	long long p=last;
	for(;p!=-1&&!SAM[p].next[c-'a'];p=SAM[p].lick){
	SAM[p].next[c-'a']=cur;
	}
	if(p==-1){
		SAM[cur].lick=0;
	}
	else{
		long long q=SAM[p].next[c-'a'];
		if(SAM[p].len+1==SAM[q].len){
			SAM[cur].lick=q;
			}else{
				int clone=cnt++;
			SAM[clone]=SAM[q]; 
			SAM[clone].len =SAM[p].len+1;
			node(cnt);
			SAM[cur].lick=SAM[q].lick=clone;
			for(;SAM[p].next[c-'a']==q&&p;p=SAM[p].lick){
				SAM[p].next[c-'a']=clone;
			}
		}
	}
	last=cur;
}
void dfs(){
	for(int i=s.size();i>0;i--){
		for(int j=head[i];j!=0;j=SAM[j].nexty){
			SAM[SAM[j].lick].cut +=SAM[j].cut;
			if(SAM[j].cut!=1)ans=max(SAM[j].cut*SAM[j].len ,ans);
		}
	}
}
int main(){
	cin>>s;
	SAM[0].lick=-1;
	for(unsigned long long i=0;i<s.size();i++){
		a=i;
		add();
	}
	dfs();
	for(long long i=1;i<=cnt;i++){
    	cout<<SAM[i].lick<<endl; 
	}
	cout<<ans;
}
2024/3/25 08:31
加载中...