萌新初学oi,码风清晰,广义sam求调
查看原帖
萌新初学oi,码风清晰,广义sam求调
421265
eastcloud楼主2023/1/22 22:16

rt,按照oiwiki的代码写的,样例输出 9,看了两小时也没看出来问题,求大佬帮忙调调 orz。

// Problem: P6139 【模板】广义后缀自动机(广义 SAM)
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P6139
// Memory Limit: 500 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
string s;
int tot=0;
struct que{
	int last,now;
};
queue<que> q;
struct Node{
	int fa,len,nex[27];
}a[2000001];
void inserttrie(string t){
	int len=t.length(),p=0;
	for(int i=0;i<len;i++){
		int num=t[i]-'a'+1;
		if(!a[p].nex[num]) a[p].nex[num]=++tot;
		else break;
		p=a[p].nex[num];
	}
}
int insertsam(int last,int num){
	int p=last,np=a[last].nex[num];
	if(a[np].len) return np;
	a[np].len=a[p].len+1;p=a[p].fa;
	for(;p!=-1 && !a[p].nex[num];p=a[p].fa) a[p].nex[num]=np;
	if(p==-1) a[np].fa=0;
	else{
		int q=a[p].nex[num];
		if(a[q].len==a[p].len+1) a[np].fa=q;
		else{
			int clone=++tot;a[clone].fa=a[q].fa;
			a[clone].len=a[p].len+1;
			for(int i=1;i<=26;i++){
				if(a[a[q].nex[i]].len)a[clone].nex[i]=a[q].nex[i];
				else a[clone].nex[i]=0;
			}
			for(;p!=-1 && a[p].nex[num]==q;p=a[p].fa) a[p].nex[num]=clone;
			a[q].fa=a[np].fa=clone;
		}
	}
	return np;
}
void build(){
	for(int i=1;i<=26;i++) if(a[0].nex[i]) q.push((que){0,i});
	while(!q.empty()){
		int num=q.front().now,last=q.front().last;q.pop();
		int cur=insertsam(last,num);
		for(int i=1;i<=26;i++)if(a[cur].nex[i])q.push((que){cur,i});
	}
}
int main(){
	int n;
	cin>>n;
	a[0].fa=-1;
	for(int i=1;i<=n;i++){
		cin>>s;
		inserttrie(s);
	}
	build();
	ll ans=0;
	for(int i=1;i<=tot;i++){
		ans+=(ll)(a[i].len-a[a[i].fa].len);
	}
	cout<<ans;
}

2023/1/22 22:16
加载中...