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);
    }
     
  • 相关阅读:
    兼容 数组 api map代码
    => 应用在js回调函数中
    let防止变量声明提前
    for-in 的坑
    call 与 apply的区别
    放大镜 鼠标滑入 鼠标滑轮放大
    js 获取元素宽
    [转]AES加密填充模式
    快被AES整崩溃了
    [转]C++ Socket编程步骤
  • 原文地址:https://www.cnblogs.com/candy99/p/6395817.html
Copyright © 2011-2022 走看看