zoukankan      html  css  js  c++  java
  • HihoCoder #1449 : 后缀自动机三·重复旋律6

    传送门
    还是后缀自动机的模板题,还是计算每个等价类的出现次数,我终于明白为什么那个 f 数组不能在 dfs 的时候赋初值了,因为从父节点中扩展出去的 nq 节点是不能为父节点贡献的。
    还缩了缩代码的长度,可以发现 sam 比 acam 还要好写,但是难理解的多。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    const int N=1e6+10;
    char s[N];
    struct SAM{
    	char *s;
    	int g[N*2][26],len[N*2],fa[N*2],f[N*2],last,tot,ans[N];
    	int head[N*2],nxt[N*2],to[N*2],total;
    	void add(int u,int v){to[++total]=v;nxt[total]=head[u];head[u]=total;}
    	int newnode(){++tot;memset(g[tot],0,sizeof(g[tot]));len[tot]=fa[tot]=f[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;return;}
    		int q=g[p][c];
    		if(len[q]==len[p]+1) {fa[np]=q;return;}
    		int nq=newnode();memcpy(g[nq],g[q],sizeof(g[nq]));fa[nq]=fa[q];len[nq]=len[p]+1;
    		fa[np]=fa[q]=nq;
    		for(;p&&g[p][c]==q;p=fa[p]) g[p][c]=nq;
    	}
    	void dfs(int u){
    		for(int i=head[u];i;i=nxt[i]) dfs(to[i]),f[u]+=f[to[i]];
    	}
    	void init(char *_s){
    		s=_s;last=newnode();
    		int strlen=0;
    		for(int i=1;s[i];i++) add(s[i]-'a'),strlen++;
    		for(int i=2;i<=tot;i++) add(fa[i],i);
    		dfs(1);
    		for(int i=1;i<=tot;i++) ans[len[i]]=max(ans[len[i]],f[i]);
    		for(int i=strlen;i>=1;i--) ans[i]=max(ans[i],ans[i+1]);
    	}
    }sam;
    
    int main(){
    	scanf("%s",s+1);
    	sam.init(s);
    	for(int i=1;s[i];i++) printf("%d
    ",sam.ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    jquery ajax参数详解
    压缩解压函数实现
    WCF 大数据量如何从服务端传到客户端
    [DllImport("kernel32.dll")]
    Oracle数据库使用基础和实例
    Js常用的动态效果
    Js使用正则实现表单验证
    Oracle数据库理论知识
    HTML5,CSS3,JavaScript基础知识与使用
    速读《人月神话》
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12618839.html
Copyright © 2011-2022 走看看