zoukankan      html  css  js  c++  java
  • HYSBZ 2565 最长双回文串 (回文树)

    2565: 最长双回文串

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1377  Solved: 714
    [Submit][Status][Discuss]

    Description

    顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
    输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分XY,(|X|,|Y|≥1)且XY都是回文串。

    Input

    一行由小写英文字母组成的字符串S

    Output

    一行一个整数,表示最长双回文子串的长度。

    Sample Input

    baacaabbacabb

    Sample Output

    12

    利用回文树统计以i为结尾的最长回文串长度和以i为开始的最长回文串的长度
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <math.h>
    #include <stdio.h>
    
    using namespace std;
    typedef long long int LL;
    const int maxn=1e5+5;
    char str[maxn];
    struct Tree
    {
        int next[maxn][26];
        int fail[maxn];
        int len[maxn];
        int s[maxn];
        int last;
        int p;
        int n;
        int new_node(int x)
        {
            memset(next[p],0,sizeof(next[p]));
            len[p]=x;
            return p++;
        }
        void init()
        {
            p=0;
            new_node(0);
            new_node(-1);
            last=0;n=0;
            s[0]=-1;
            fail[0]=1;
        }
        int get_fail(int x)
        {
            while(s[n-len[x]-1]!=s[n])
                x=fail[x];
    		return x;
        }
        int add(int x)
        {
            x-='a';
            s[++n]=x;
            int cur=get_fail(last);
            if(!(last=next[cur][x]))
            {
                int now=new_node(len[cur]+2);
                fail[now]=next[get_fail(fail[cur])][x];
                next[cur][x]=now;
                last=now;
            }
            return len[last];
        }
    }tree;
    int s1[maxn];
    int s2[maxn];
    int main()
    {
        while(scanf("%s",str)!=EOF)
        {
            int len=strlen(str);
            tree.init();
            memset(s1,0,sizeof(s1));
            memset(s2,0,sizeof(s2));
            for(int i=0;i<len;i++)
            {
                s1[i]=tree.add(str[i]);
            }
            tree.init();
            for(int i=len-1;i>=0;i--)
            {
                s2[i]=tree.add(str[i]);
            }
            int ans=0;
            for(int i=0;i<len;i++)
            {
                ans=max(ans,s1[i]+s2[i+1]);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    大话设计模式---单一职责原则
    大话设计模式---策略模式
    计算机网络(二)
    计算机网络(一)
    栈与队列

    数据库面试题——基本概念
    链表
    【Essential c++】——(三)泛型编程风格
    【转载】学习JAVA WEB的路线
  • 原文地址:https://www.cnblogs.com/dacc123/p/8228635.html
Copyright © 2011-2022 走看看