zoukankan      html  css  js  c++  java
  • SPOJ_NSUBSTR

    题目意思是给你一个字符串,f[x]是长度为x的子串中,出现个数最多的那个串的出现次数。

    给出原串,依次输出f[1],f[2],……。

    后缀自动机。对于某一个状态,right[]值的大小就是出现的次数,而且是对于长为step[]的子串的出现次数。

    因为小于step值的串在前面已经加了,在pre指针线上面的状态要把当前数量累加上去即可。

    不过注意这里要先拓扑排序,这样才能保证更新的正确性。恩,很实用很不错的一种拓扑排序方式。新技能get。

    召唤代码君:

    #include <iostream>
    #include <cstdio>
    #define maxn 500500
    using namespace std;
    
    int next[maxn][26],pre[maxn],step[maxn],dp[maxn],g[maxn],Q[maxn],cnt[maxn];
    int N,last,p,q,np,nq;
    char s[maxn];
    
    void insert(int x,int m)
    {
    	p=last,np=++N,step[np]=m,last=np,g[np]++;
    	while (p!=-1 && next[p][x]==0)
            next[p][x]=np,p=pre[p];
    	if (p==-1) return ;
    	q=next[p][x];
    	if (step[q]==step[p]+1)
            { pre[np]=q; return; }
    	nq=++N,step[nq]=step[p]+1,pre[nq]=pre[q];
    	for (int i=0; i<26; i++)
            next[nq][i]=next[q][i];
          pre[np]=pre[q]=nq;
    	while (p!=-1 && next[p][x]==q)
            next[p][x]=nq,p=pre[p];
    }
    
    int main()
    {
    	pre[0]=-1;
    	scanf("%s",s);
    	for (int i=0; s[i]; i++) insert(s[i]-'a',i+1);
    	for (int i=1; i<=N; i++) cnt[step[i]]++;
    	for (int i=1; i<=N; i++) cnt[i]+=cnt[i-1];
    	for (int i=1; i<=N; i++) Q[cnt[step[i]]--]=i;
    	for (int i=N; i>=1; i--) dp[step[Q[i]]]=max(dp[step[Q[i]]],g[Q[i]]),g[pre[Q[i]]]+=g[Q[i]];
    	for (int i=1; s[i-1]; i++) printf("%d
    ",dp[i]);
    	return 0;
    }
    

      

    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    笔记44 Hibernate快速入门(一)
    tomcat 启用https协议
    笔记43 Spring Security简介
    笔记43 Spring Web Flow——订购披萨应用详解
    笔记42 Spring Web Flow——Demo(2)
    笔记41 Spring Web Flow——Demo
    Perfect Squares
    Factorial Trailing Zeroes
    Excel Sheet Column Title
    Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/lochan/p/3799720.html
Copyright © 2011-2022 走看看