• SPOJ


    You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string 'ababa' F(3) will be 2 because there is a string 'aba' that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.

    Input

    String S consists of at most 250000 lowercase latin letters.

    Output

    Output |S| lines. On the i-th line output F(i).

    Example

    Input:
    ababa

    Output:
    3
    2
    2
    1
    1

    依次输出“出现次数最多的长度为x的字符串”的出现次数 (1<=x<=n)

    后缀自动机

    建出后缀自动机,统计每个节点标记的长度的出现次数即可。注意要倒序更新,把子节点(长串)的值累加到fa结点(长串的子串)的值上。

      ↑建好后缀自动机以后,要用原串在自动机上跑一便,每一个到达结点的初始次数r置为1。刚开始傻傻地把所有节点的r都初始化成1了,导致统计错误(理解不透彻)

    顿悟:把后缀自动机的fa指针看成fail而不是father更直观 ←大概是我自己火星了)

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8 const int mxn=500010;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 struct SAM{
    16     int t[mxn][26];
    17     int fa[mxn],l[mxn],r[mxn],rk[mxn];
    18     int S,cnt,last;
    19     int f[mxn],w[mxn];
    20     void init(){S=cnt=last=1;return;}
    21     void add(int c){
    22         int p=last,np=++cnt;last=np;
    23         l[np]=l[p]+1;
    24         for(;p && !t[p][c];p=fa[p])t[p][c]=np;
    25         if(!p){fa[np]=S;}
    26         else{
    27             int q=t[p][c];
    28             if(l[q]==l[p]+1){fa[np]=q;}
    29             else{
    30                 int nq=++cnt;l[nq]=l[p]+1;
    31                 memcpy(t[nq],t[q],sizeof t[q]);
    32                 fa[nq]=fa[q];
    33                 fa[np]=fa[q]=nq;
    34                 for(;p && t[p][c]==q;p=fa[p])t[p][c]=nq;
    35             }
    36         }
    37     }
    38     void st(char *s,int n){
    39 //        for(int i=1;i<=cnt;i++){r[i]=1;w[l[i]]++;}
    40         int p=S;
    41         for(int i=1;i<=n;i++){
    42             p=t[p][s[i]-'a'];
    43             r[p]++;
    44         }
    45         for(int i=1;i<=cnt;i++){w[l[i]]++;}
    46         for(int i=1;i<=n;i++)w[i]+=w[i-1];
    47         for(int i=1;i<=cnt;i++)rk[w[l[i]]--]=i;
    48         return;
    49     }
    50     void solve(int n){
    51         for(int i=cnt;i;i--){
    52             int t=rk[i];
    53             f[l[t]]=max(f[l[t]],r[t]);
    54             r[fa[t]]+=r[t];
    55         }
    56         for(int i=n-1;i;i--)f[i]=max(f[i],f[i+1]);
    57         return;
    58     }
    59 }sa;
    60 char s[mxn];
    61 int main(){
    62     int i,j;
    63     sa.init();
    64     scanf("%s",s+1);
    65     int len=strlen(s+1);
    66     for(i=1;i<=len;i++){
    67         sa.add(s[i]-'a');
    68     }
    69     sa.st(s,len);
    70     sa.solve(len);
    71     for(i=1;i<=len;i++)printf("%d
    ",sa.f[i]);
    72     return 0;
    73 }
  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6420565.html
Copyright © 2020-2023  润新知