1 条题解

  • 0
    @ 2025-8-24 22:11:57

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar mrsrz
    故障机器人

    搬运于2025-08-24 22:11:57,当前版本为作者最后更新于2019-09-12 19:15:51,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    为啥知道有回文自动机还要写带log的std啊

    为啥放那么小范围放那么大时限啊

    我记得我前几天刚刚放了PAM板子啊

    前置芝士:回文自动机。不懂的可以去窝的模板那儿看看。

    这个题问你最长公共回文子串长度和个数。

    我们对两个字符串分别建回文自动机。回文自动机中的转移边形成了一个树形结构。

    走相同的转移边,得到的回文串显然是相同的。

    那么我们同时对两棵树进行dfs,每次都走相同的转移边,那么走到的每个节点代表的回文串一定是公共的。

    这样就可以统计最长长度了。又由于回文自动机中每个节点代表的回文串不同,所以也可以同时统计出不同最长公共回文子串个数。

    回文自动机的点数是O(n)O(n),所以总时间复杂度O(n)O(n)

    比std短,比std快,还比std好写。

    Code:

    #include<cstdio>
    const int N=3e5+5;
    char s[N],ss[N];
    int mx=0,tot=0,n,m;
    struct pam{
        int len[N],fail[N],ch[N][26],tot,lst,num[N];
        char s[N];
        void init(char*ss){
            tot=lst=1;
            len[1]=-1,len[0]=0,fail[0]=1;
            for(int i=1;ss[i];++i)s[i]=ss[i];
        }
        int insert(char cr,int ed){
            int c=cr-'a';
            int p=lst;
            while(s[ed]!=s[ed-len[p]-1])
            p=fail[p];
            if(!ch[p][c]){
                int np=++tot;
                len[np]=len[p]+2;
                int q;
                for(q=fail[p];s[ed]!=s[ed-len[q]-1];q=fail[q]);
                fail[np]=ch[q][c];
                num[np]=num[fail[np]]+1;
                ch[p][c]=np;
            }
            lst=ch[p][c];
            return num[lst];
        }
    }p1,p2;
    void dfs(int nl,int nr){
        if(mx<p1.len[nl])mx=p1.len[nl],tot=1;else
        if(mx==p1.len[nl])++tot;
        for(int i=0;i<26;++i)
        if(p1.ch[nl][i]&&p2.ch[nr][i])dfs(p1.ch[nl][i],p2.ch[nr][i]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        scanf("%s%s",s+1,ss+1);
        p1.init(s),p2.init(ss);
        for(int i=1;s[i];++i)
        p1.insert(s[i],i);
        for(int i=1;ss[i];++i)
        p2.insert(ss[i],i);
        dfs(0,0);
        dfs(1,1);
        printf("%d %d\n",mx,tot);
        return 0;
    }
    
    
    • 1

    信息

    ID
    4488
    时间
    3000ms
    内存
    500MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者