• 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
    F(x)表示S的所有长度为x的子串中,出现次数的最大值,题意为输出F(1),F(2).......F(n).
    分析:
    从根节点,到主轴上的每个一个节点的数量都赋为数量1,表示根节点到该节点形成的子串数量初始为1(非主轴上的节点是主轴上节点的状态分移出来的,所以初始的时候不赋值,通过后缀链接再赋值)
    这样的话,一个节点的后缀链接的num就等于该节点的num+1,对于每个节点,都记录该节点长度出现的子串数量最大值即可
    代码如下:
    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <stdio.h>
    
    using namespace std;
    const int N=250010;
    typedef long long ll;
    struct State
    {
        State *link,*go[26];
        int step;
        int num;
        void clear()
        {
            num=0;
            link=0;
            step=0;
            memset(go,0,sizeof(go));
        }
    }*root,*last;
    int cnt[N];
    int lenA;
    State statePool[N*2],*b[N*2],*cur;
    
    void init()
    {
        cur=statePool;
        root=last=cur++;
        root->clear();
    }
    
    void Insert(int w)
    {
        State *p=last;
        State *np=cur++;
        np->clear();
        np->step=p->step+1;
        while(p&&!p->go[w])
            p->go[w]=np,p=p->link;
        if(p==0)
            np->link=root;
        else
        {
            State *q=p->go[w];
            if(p->step+1==q->step)
                np->link=q;
            else
            {
                State *nq=cur++;
                nq->clear();
                memcpy(nq->go,q->go,sizeof(q->go));
                nq->step=p->step+1;
                nq->link=q->link;
                q->link=nq;
                np->link=nq;
                while(p&&p->go[w]==q)
                    p->go[w]=nq, p=p->link;
            }
        }
        last=np;
    }
    
    void tsort()
    {
        memset(cnt,0,sizeof(cnt));
        State *p;
        for(p=statePool;p!=cur;p++)
          cnt[p->step]++;
        for(int i=1;i<=lenA;i++)
          cnt[i]+=cnt[i-1];
        for(p=statePool;p!=cur;p++)
          b[--cnt[p->step]]=p;
    }
    char A[N],B[N];
    int ans[N];
    int main()
    {
            while(scanf("%s",A)!=EOF){
            init();
            lenA=strlen(A);
            for(int i=0;i<lenA;i++)
             Insert(A[i]-'a');
            tsort();
           memset(ans,0,sizeof(ans));
            State *p;
            p=root;
            for(int i=0;i<lenA;i++)
            {
                int x=A[i]-'a';
               p=p->go[x];
               p->num=1;
            }
           int L=cur-statePool;
           for(int i=L-1;i>0;i--)
           {
               p=b[i];
               ans[p->step]=max(ans[p->step],p->num);
               p->link->num+=p->num;
           }
           for(int i=lenA-1;i>=1;i--)
            ans[i]=max(ans[i],ans[i+1]);
           for(int i=1;i<=lenA;i++)
           {
               printf("%d
    ",ans[i]);
           }
            }
        return 0;
    }
  • 相关阅读:
    netty
    python统计订单走势
    log4j日志写入数据库
    struts 在Action中访问web元素(request,session等)
    struts 简单前台用户名校验
    struts 页面调用Action的指定方法并传递参数
    简单的对象监听器 观察者设计模式
    servlet 简单filter避免中文乱码等
    Struts 第一个Hello页面
    JDBC 使用SimpleJdbcTemplate实现Dao
  • 原文地址:https://www.cnblogs.com/a249189046/p/7704636.html
Copyright © 2020-2023  润新知