【模板】后缀自动机

学习资料
https://www.luogu.com.cn/blog/Kesdiael3/hou-zhui-zi-dong-ji-yang-xie
(广义后缀自动机) https://www.cnblogs.com/Xing-Ling/p/12038349.html

【模板】后缀自动机 (SAM) https://www.luogu.com.cn/problem/P3804

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct NODE {
	int ch[26];
	int len,fa;
}dian[N<<1];
int las=1,tot=1;
char s[N];
int len,siz[N<<1],a[N<<1],c[N<<1];
long long res;
void add(int c) {
	int p=las;int np=las=++tot;
	dian[np].len=dian[p].len+1;
	for(;p&&!dian[p].ch[c];p=dian[p].fa) dian[p].ch[c]=np;
	if(!p) dian[np].fa=1;
	else {
		int q=dian[p].ch[c];
		if(dian[q].len==dian[p].len+1) dian[np].fa=q; 
		else { 
			int nq=++tot; dian[nq]=dian[q]; 
			dian[nq].len=dian[p].len+1; 
			dian[q].fa=dian[np].fa=nq; 
			for(;p&&dian[p].ch[c]==q;p=dian[p].fa) dian[p].ch[c]=nq; 
		}
	}
	siz[np]=1;
}
void dfs(int u) {
	siz[u]=1;
	for(int i=0;i<26;i++)
	    if(dian[u].ch[i]) {
	    	dfs(dian[u].ch[i]);
	    	siz[u]+=siz[dian[u].ch[i]];
		}
}
int main() {
	scanf("%s",s); len=strlen(s);
	for(int i=0;i<len;i++) add(s[i]-'a');
	for(int i=1;i<=tot;i++)c[dian[i].len]++;
    for(int i=1;i<=tot;i++)c[i]+=c[i-1];
    for(int i=1;i<=tot;i++)a[c[dian[i].len]--]=i;
    for(int i=tot;i;i--){
        int p=a[i];
        siz[dian[p].fa]+=siz[p];
        if(siz[p]>1) res=max(res,1LL*siz[p]*dian[p].len);
    }
	printf("%lld",res);
}

[NOI2015] 品酒大会

posted @ 2022-07-28 19:08  仰望星空的蚂蚁  阅读(11)  评论(0)    收藏  举报  来源