• 洛谷 P3804 【模板】后缀自动机 (SAM)


    传送门
    终于搞懂了这个东西,以后会多做几道后缀自动机的题的,顺便复习一下后缀数组。
    这篇博客讲后缀自动机讲的很不错,推荐初学者看这篇博客学习。
    后缀自动机还有很多的性质我还不是很懂,靠之后做的题来补就是了。
    这道题最后的清算有两种办法,一种是重新建图dfs,比较方便,还有一种就是按长度对节点进行基数排序,结果就是par树的拓扑序列,然后倒着加。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <queue>
    using namespace std;
    typedef long long LL;
    const int N=1e6+10;
    char s[N];
    struct SAM{
    	char *s;
    	int g[N*2][26],fa[N*2],last,tot,len[N*2],f[N*2];
    	vector<int> tr[N*2];
    	LL ans;
    	int newnode(){++tot;memset(g[tot],0,sizeof(g[tot]));fa[tot]=len[tot]=0;return tot;}
    	void add(int c){
    		int p=last,np=last=newnode();
    		len[np]=len[p]+1;f[np]=1;
    		for(;p&&!g[p][c];p=fa[p]) g[p][c]=np;
    		if(!p) fa[np]=1;
    		else{
    			int q=g[p][c];
    			if(len[q]==len[p]+1) fa[np]=q;
    			else{
    				int nq=newnode();memcpy(g[nq],g[q],sizeof(g[nq]));fa[nq]=fa[q];
    				len[nq]=len[p]+1;
    				fa[q]=fa[np]=nq;
    				for(;p&&g[p][c]==q;p=fa[p]) g[p][c]=nq;
    			}
    		}
    	}
    	void dfs(int u){
    		for(int v:tr[u]) dfs(v),f[u]+=f[v];
    		if(f[u]>1) ans=max(ans,1ll*f[u]*len[u]);
    	}
    	void init(char *_s){
    		s=_s;last=newnode();
    		for(int i=1;s[i]!='';i++) add(s[i]-'a');
    		for(int i=2;i<=tot;i++) tr[fa[i]].push_back(i);
    		dfs(1);
    	}
    }sam;
    
    
    int main(){
    	scanf("%s",s+1);
    	sam.init(s);
    	printf("%lld
    ",sam.ans);
    	return 0;
    }
    
  • 相关阅读:
    条码解析的一片js
    再看.net本质(二)
    再看.net本质
    powerdesigner逆向导出oracle数据库结构显示备注
    powerdesigner逆向工程,从数据库导出PDM
    实现HTTP跳转到HTTPS
    opencart 模块开发详解
    Opencart 之 Registry 类详解
    OpenCart 之registry功用
    php+支付宝整合
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12618139.html
Copyright © 2020-2023  润新知