zoukankan      html  css  js  c++  java
  • BZOJ 2565: 最长双回文串 [Manacher]

    2565: 最长双回文串

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1842  Solved: 935
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Manacher后处理每个#左右最长被以L R为中心的回文串覆盖
    答案用R-L来更新
     
    我迷之TLE了40min
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=3e5+5;
    typedef long long ll;
    int n;
    char s[N],str[N];
    int r[N];
    void Manacher(char s[],int n){
        int p=0,a;
        for(int i=1;i<=n;i++){
            r[i]=i<p?min(p-i+1,r[2*a-i]):1;
            while(s[i-r[i]]==s[i+r[i]]) r[i]++;
            if(i+r[i]-1>p) p=i+r[i]-1,a=i;
        }
    }
    void iniStr(char str[],char s[]){
        for(int i=1;i<=n;i++)
            s[(i<<1)-1]='#',s[i<<1]=str[i];
        s[n<<1|1]='#';
        s[0]='@';s[(n<<1)+2]='$';
    }
    int l[N];
    int main(){
        freopen("in","r",stdin);
        scanf("%s",str+1);
        n=strlen(str+1);
        iniStr(str,s);
        Manacher(s,n<<1|1);
        n=n<<1|1;
        int now=1,ans=0;
        for(int i=1;i<=n;i++){
            while(now+r[now]-1<i) now++;
            l[i]=now;
        }
        now=n;
        for(int i=n;i>=1;i--){
            while(now-r[now]+1>i) now--;
            if(i&1) ans=max(ans,now-l[i]);
        }
        printf("%d",ans);
    }
     
  • 相关阅读:
    Android:Butter Knife 8.0.1配置
    webAPI获得链接客户端IP地址
    解决WebClient或HttpWebRequest首次连接缓慢问题
    Android Studio中有用的快捷键栏
    SQL十进制和十六进制相互转换
    SQL分组查询每组前几条数据
    POJ 1011 Sticks
    POJ 1144 Network(割点)
    求无向图中的割边(桥)
    POJ 2553 The Bottom of a Graph
  • 原文地址:https://www.cnblogs.com/candy99/p/6395817.html
Copyright © 2011-2022 走看看