zoukankan      html  css  js  c++  java
  • 【CF835D】Palindromic characteristics 加强版 解题报告

    【CF835D】Palindromic characteristics 加强版

    Description

    给你一个串,让你求出(k)阶回文子串有多少个。(k)(1)(n)

    (k)阶子串的定义是:子串本身是回文串,而且它的左半部分也是回文串。

    首先明确:

    1. 如果一个串是(k)阶回文,那他一定还是(k-1)阶回文。

    2. 如果一个串是(k)阶回文,那么这个串需要满足:

    • 它本是是回文的。
    • 他的左半部分是(k-1)回文的。

    Input

    一个字符串(s)

    Output

    (n)行。第(i)行输出(s)有多少个子串是(i−)回文串。

    HINT

    对于(100\%)的数据:(1≤n≤5000000)$仅包含小写字母


    思路:建出(PAM)之后维护一个(f_i)代表长度小于一半的最长回文后缀,不要暴力去更新(Ta),也不用调跳倍增,直接借助父亲节点的这个数组缩小一半的范围就是(O(n))的了。


    Code:

    #include <cstdio>
    #include <cstring>
    #define ll long long
    const int N=5e3+10;
    char s[N];
    int ch[N][26],len[N],fail[N],kth[N],f[N],n,tot;
    ll ans[N],siz[N];
    int getfail(int now,int p)
    {
        while(s[p]!=s[p-len[now]-1]) now=fail[now];
        return now;
    }
    void PAM()
    {
        len[0]=0,len[++tot]=-1,f[0]=fail[0]=1;
        scanf("%s",s+1);n=strlen(s+1);
        for(int las=0,i=1;i<=n;i++)
        {
            int cur=getfail(las,i),c=s[i]-'a';
            if(!ch[cur][c])
            {
                int now=++tot;
                fail[now]=ch[getfail(fail[cur],i)][c];
                ch[cur][c]=now;
                len[now]=len[cur]+2;
                if(len[fail[now]]<=len[now]>>1) f[now]=fail[now];
                else
                {
                    int p=f[cur];
                    while((len[p]+2>len[now]>>1)||(s[i]!=s[i-len[p]-1])) p=fail[p];
                    f[now]=ch[p][c];
                }
            }
            ++siz[las=ch[cur][c]];
        }
        for(int i=tot;i;i--) siz[fail[i]]+=siz[i];
        for(int i=2;i<=tot;i++)
        {
            if(len[f[i]]==len[i]>>1)
                kth[i]=kth[f[i]]+1;
            else
                kth[i]=1;
            ans[kth[i]]+=siz[i];
        }
    }
    int main()
    {
        PAM();
        for(int i=n;i;i--) ans[i]+=ans[i+1];
        for(int i=1;i<=n;i++) printf("%lld
    ",ans[i]);
        return 0;
    }
    

    2018.12.14

  • 相关阅读:
    【转】如何解决Verilog中参数化的赋值:赋全0,赋全1,赋全Z,赋全x
    【转】PCIe DMA
    【转】PCIe学习(二)——PCIe DMA关键模块分析之一
    PCIe配置空间
    [转]PCIe学习笔记之MSI/MSI-x中断及代码分析
    [转]常用通信接口保护电路
    [转]原理图和PCB元件对应查找--Altium Designer
    [原]PCB中MARK点制作
    [转]使用Altium Designer软件铺铜后再挖铜
    支持Json进行操作的Javascript类库TAFFY DB
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10121055.html
Copyright © 2011-2022 走看看