• hihoCoder 后缀自动机三·重复旋律6


    后缀自动机三·重复旋律6

    时间限制:15000ms
    单点时限:3000ms
    内存限制:512MB

    描述

    小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为一段数构成的数列。

    现在小Hi想知道一部作品中所有长度为K的旋律中出现次数最多的旋律的出现次数。但是K不是固定的,小Hi想知道对于所有的K的答案。

    解题方法提示

    输入

    共一行,包含一个由小写字母构成的字符串S。字符串长度不超过 1000000。

    输出

    共Length(S)行,每行一个整数,表示答案。

    样例输入
    aab
    样例输出
    2
    1
    1

    小Hi讲的实在太好了,就不说什么了。

      1 /*************************************************************************
      2     > File: main.cpp
      3     > Author: You Siki
      4     > Mail: You.Siki@outlook.com 
      5     > Time: 2016年12月23日 星期五 15时14分18秒
      6  ************************************************************************/
      7 
      8 #include<bits/stdc++.h>
      9 
     10 //using namespace std;
     11 
     12 const int maxn = 2000005;
     13 
     14 /* AUTOMATON */
     15 
     16 int last = 1;
     17 int tail = 2;
     18 int fail[maxn];
     19 int step[maxn];
     20 int flag[maxn];
     21 int next[maxn][26];
     22 
     23 inline void buildAutomaton(char *s)
     24 {
     25     while (*s)
     26     {
     27         int p = last;
     28         int t = tail++;
     29         int c = *s++ - 'a';
     30 
     31         flag[t] = true;
     32         step[t] = step[p] + 1;
     33 
     34         while (p && !next[p][c])
     35             next[p][c] = t, p = fail[p];
     36 
     37         if (p)
     38         {
     39             int q = next[p][c];
     40             if (step[q] == step[p] + 1)
     41                 fail[t] = q;
     42             else
     43             {
     44                 int k = tail++;
     45                 fail[k] = fail[q];
     46                 fail[q] = fail[t] = k;
     47                 step[k] = step[p] + 1;
     48                 for (int i = 0; i < 26; ++i)
     49                     next[k][i] = next[q][i];
     50                 while (p && next[p][c] == q)
     51                     next[p][c] = k, p = fail[p];
     52             }
     53         }
     54         else
     55             fail[t] = 1;
     56         last = t;
     57     }
     58 }
     59 
     60 int que[maxn];
     61 int cnt[maxn];
     62 int ans[maxn];
     63 
     64 inline int solveAndPrintAnswer(char *s)
     65 {
     66     int hd = 0, tl = 0, n = strlen(s);
     67 
     68     for (int i = 1; i < tail; ++i)
     69         ++cnt[fail[i]];
     70 
     71     for (int i = 1; i < tail; ++i)
     72         if (!cnt[i])que[tl++] = i;
     73 
     74     while (hd != tl)
     75     {
     76         int t = que[hd++];
     77         flag[fail[t]] += flag[t];
     78         if (--cnt[fail[t]] == 0)
     79             que[tl++] = fail[t];
     80     }
     81 
     82     for (int i = 1; i < tail; ++i)
     83         if (ans[step[i]] < flag[i])
     84             ans[step[i]] = flag[i];
     85 
     86     for (int i = n; i; --i)
     87         if (ans[i] < ans[i + 1])
     88             ans[i] = ans[i + 1];
     89 
     90     for (int i = 1; i <= n; ++i)
     91         printf("%d
    ", ans[i]);
     92 }
     93 
     94 /* MAIN FUNC */
     95 
     96 char str[maxn];
     97 
     98 signed main(void) 
     99 {
    100     scanf("%s", str);
    101     buildAutomaton(str);
    102     solveAndPrintAnswer(str);
    103 }

    @Author: YouSiki

  • 相关阅读:
    HTTP状态码表
    统计各国访客插件 flag counter
    获取和设置cookie的方法(5种)
    最简单的方式创建node.js 静态服务器
    js中map,forEach,filter,reduce等方法是ECMAScript5 Array新增方法
    ECMAScript各个版本简介及特性
    JSON的parse()和stringfy()方法
    javascript中的错误对象error
    JS window对象的top、parent、opener含义介绍
    postman的使用总结
  • 原文地址:https://www.cnblogs.com/yousiki/p/6215041.html
Copyright © 2020-2023  润新知