• hiho#1449 重复旋律6 求长度为k的串最大次数 后缀自动机


    题目传送门

    题目大意:求长度为k的串的最大次数,把k从1到length的所有答案全部输出。

    思路:

      这道题放在$SAM$里就是求长度$k$对应的所有$right$集中最大的大小。

      我们以$aabab$这个串距离,称作$S$串。

      首先我们要求出每一个状态对应的right集大小,S中的aab和ab此时并不在一个模式下,但他们属于一个right集,而ab是aab的父串,所以我们用拓扑排序的方式得到right集,这里的更新操作是$+$,因为ab对应的模式此时并没有包含aab中的ab。

      而得到right后,我们会发现在SAM上并没有一个单独的模式对应b,因为b被包含在了ab这个模式里面,所以我们也要用长度为2的答案来更新长度为1的答案,这里是取max,因为有可能是重复的,比如$abab$这样的串。

    #include<bits/stdc++.h>
    #define clr(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int maxn=1000010;
    char s[maxn];
    int len[maxn<<1],ch[maxn<<1][27],fa[maxn<<1],tot=1,root=1,last=1,siz,r[maxn<<1];
    int a[maxn<<1],c[maxn<<1],ans[maxn<<1];
    void extend(int x){
        int now=++tot,pre=last;
        r[now]=1;
        last=now,len[now]=len[pre]+1;
        while( pre && !ch[pre][x]){
            ch[pre][x]=now;
            pre=fa[pre];
        }
        if(!pre)fa[now]=root;
        else{
            int q = ch[pre][x];
            if(len[q]==len[pre]+1)fa[now]=q;
            else {
                int nows=++tot;
                memcpy(ch[nows],ch[q],sizeof(ch[q]));
                len[nows]=len[pre]+1;
                fa[nows]=fa[q];
                fa[q]=fa[now]=nows;
                while(pre&&ch[pre][x]==q){
                    ch[pre][x]=nows;
                    pre=fa[pre];
                }
            }
        }
    }
    void topSort(){
        for(int i=1;i<=tot;i++)c[len[i]]++;
        for(int i=1;i<=tot;i++)c[i]+=c[i-1];
        for(int i=tot;i>0;i--)a[c[len[i]]--]=i;
        for(int i=tot;i>0;i--)r[fa[a[i]]]+=r[a[i]];
    }
    int main(){
        scanf("%s",s);
        siz=strlen(s);
        for(int i=0;i<siz;i++)
        {
            int p=s[i]-'a';
            extend(p);
        }
        topSort();
        for(int i=1;i<=tot;i++)ans[len[i]]=max(ans[len[i]],r[i]);
        for(int i=siz-1;i>0;i--)ans[i]=max(ans[i+1],ans[i]);
        for(int i=1;i<=siz;i++)printf("%d
    ",ans[i]);
    
    }
  • 相关阅读:
    opengl学习
    同步、异步、多线程与事件型综述
    Javascript异步编程的4种方法
    ASP.NET(C#) GridView (编辑、删除、更新、取消)
    浅析五大ASP.NET数据控件
    用 Eclipse 开发 Android 应用程序
    [C# 网络编程系列]专题十:实现简单的邮件收发器
    [C# 网络编程系列]专题九:实现类似QQ的即时通信程序
    [C# 网络编程系列]专题七:UDP编程补充——UDP广播程序的实现
    [C# 网络编程系列]专题六:UDP编程
  • 原文地址:https://www.cnblogs.com/mountaink/p/10665040.html
Copyright © 2020-2023  润新知