【悬关】后缀自动机,88分,WA了7和9,求调
查看原帖
【悬关】后缀自动机,88分,WA了7和9,求调
317008
青溪白石楼主2024/2/27 19:38
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 250010 * 2;
int len[maxn], lnk[maxn];
int nxt[maxn][26];
int last, cur;
int ans[maxn];
struct SAM{
	void init(){
		cur = last = 0;
		memset(nxt, 0, sizeof nxt);
		memset(len, 0, sizeof len);
		memset(lnk, 0, sizeof lnk); 
		len[last] = 0;
		lnk[last] = -1;
	}
	void newnode(){
		cur++;
		for(int i = 0; i < 26; i++){
			nxt[cur][i] = 0;
		}
	}
	void insert(char ch){
		//ch -= 'a';
		newnode();
		len[cur] = len[last]+1;
		int p = last;
		last = cur;
		while(p != -1 && !nxt[p][ch]){
			nxt[p][ch] = cur;
			p = lnk[p];
		}
		if(p == -1){
			lnk[cur] = 0;
			return;
		}
		int q = nxt[p][ch];
		if(len[q] == len[p]+1){
			lnk[cur] = q;
			return;
		}
		newnode();
		int nq = cur;
		len[nq] = len[p]+1;
		lnk[nq] = lnk[q];
		for(int i = 0; i < 26; i++){
			nxt[nq][i] = nxt[q][i];
		}
		while(p != -1 && nxt[p][ch] == q){
			nxt[p][ch] = nq;
			p = lnk[p];
		}
		lnk[q] = lnk[last] = nq;
	}
}sam;
int mx[maxn], cnt[maxn], deg[maxn];
bool vis[maxn];
int ord[maxn], ptr;
void toposort(){
   	queue<int> Q;
   	for(int i = 1; i <= cur; i++){
   		for(char ch = 0; ch < 26; ch++){
   			if(nxt[i][ch]) deg[nxt[i][ch]]++;
		}
	}
	for(int i = 1; i <= cur; i++){
		if(!deg[i]) Q.push(i);
	}
	while(!Q.empty()){
		int p = Q.front(); Q.pop();
		ord[ptr++]=p;
		vis[p] = 1;
		for(int i = 0; i < 26; i++){
			int u = nxt[p][i];
			if(u){
				deg[u]--;
				if(!deg[u]){
					Q.push(u);
				}
			}
		}
	}
}
void lcs(const string t){
	int v = 0, l = 0;
	for(int i = 0; i < t.size(); i++){
		while(!nxt[v][t[i]-'a']){
			v = lnk[v];
			if(v == -1){
				v = l = 0;
				break;
			}
			l = len[v];
		}
		if(nxt[v][t[i]-'a']){
			l++;
			v = nxt[v][t[i]-'a'];
			mx[v] = max(mx[v], l);
		}
	}
	for(int i = 0; i < ptr; i++){
		int now = ord[i], pa = lnk[now];
		mx[pa] = max(mx[pa], min(mx[now], len[pa]));
		ans[now] = min(ans[now], mx[now]);
		mx[now] = 0;
	}
}
const int maxk = 10;
string s;
int main(){
	int n; cin >> n;
	sam.init();
	for(int i = 0; i < n; i++){
		cin >> s;
		if(!i){
			for(int j = 0; j < s.size(); j++){
				sam.insert(s[j]-'a');
			}
			toposort();
			for(int j = 0; j < cur; j++){
				ans[j] = len[j];
			}
		}
		else lcs(s);
	}
	int Ans = 0;
	for(int j = 1; j <= cur; j++){
		//cout << ans[j] << " ";
		Ans = max(Ans, ans[j]);
	}
	cout << Ans;
}
2024/2/27 19:38
加载中...