模板

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
;
];
], id, mx=;
int L, R; //回文串在原串的左右端点位置

int Init()
{
    int len = strlen(s);
    sNew[] = '$';
    sNew[] = '#';
    ;
    ; i < len; i++){
        sNew[j++] = s[i];
        sNew[j++] = '#';
    }
    sNew[j] = '\0';
    return j;
}

int Manacher()
{
    int len = Init();
    ;
    mx = ;
    ; i < len; i++){
         * id - i], mx - i);
        ;

        ///在对象不是字符串时候,原本为了防止越界是左有'$'
        ///右有'\0',现在右边就没有'\0',需要人为填充替代!

        while (sNew[i - p[i]] == sNew[i + p[i]]) p[i]++;

        if (mx < i + p[i]){
            id = i;
            mx = i + p[i];
        }

        //max_len = max(max_len, p[i] - 1);

////      如果题目不要求输出回文串在原串的位置,则用下面代码更新答案
        if(max_len < p[i]){ ///这里L、R记录的是最长回文子串在原串的左右端点
            max_len = p[i];
            L = (i - p[i])>>;
            R = (i + p[i] - )>>; ///R = (i + p[i])/2 -2;
        }

    }
    return max_len;

///    最后如若需要找到的回文串则是
///    for(int i=(id-mx+1);i<=(id+mx-1);i++)
///         if(sNew[i]!='#'&&sNew[i]!='$') ///注意你设置的开头符号和填充符号,不同则需要修改
///             putchar(sNew[i]);
}

p[i]-1 为以 i 为中心的回文长度

p[i]/2 表示回文半径

i%2==0 表示这个位置为字符,i/2-1 表示原字符串的位置

i%2==1 表示为字符中间,这两边的字符在原字符串的位置分别为 i/2-1 和 i/2

问题提出 : 给出一个串,要求在O(n)时间复杂度内计算出最长的回文子串

分析参考==> https://www.61mon.com/index.php/archives/181/  or  https://www.felix021.com/blog/read.php?2040

相关题目 :

HDU 3068

题意 : 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.

分析 : 模板题

POJ 3974

题意 : 给出一个串,求最长回文子串

分析 : 还是模板题

③ 吉哥系列故事――完美队形II

题意 : 中文题就不复述了

分析 : 实际上还是模板题,只要在回文判断两边相等的代码上加上递增这一条件即可

#include <iostream>
#include <cstring>
#include <algorithm>
#include<stdio.h>
using namespace std;
;
const int INF  = 0x3f3f3f3f;
];
], id, mx=;
int len;
int Init()
{
    s_new[] = -;
    s_new[] = INF;
    ;
    ; i < len; i++){
        s_new[j++] = s[i];
        s_new[j++] = INF;
    }
    return j;  // 返回 s_new 的长度
}

int Manacher()
{
    int len = Init();  // 取得新字符串长度并完成向 s_new 的转换
    ;  // 最长回文长度
    mx = ;
    ; i < len; i++){
         * id - i], mx - i);  // 需搞清楚上面那张图含义, mx 和 2*id-i 的含义
        ;

        while (s_new[i - p[i]] == s_new[i + p[i]]
               && s_new[i - p[i]] <= s_new[i - p[i] + ]) p[i]++;// 不需边界判断,因为左有'$',右有'\0'

        if (mx < i + p[i]){
            id = i;
            mx = i + p[i];
        }

        max_len = max(max_len, p[i] - );
    }
    return max_len;
///    最后如若需要找到的回文串则是
///    for(int i=(id-mx+1);i<=(id+mx-1);i++)
///         if(s_new[i]!='#'&&s_new[i]!='$')
///             putchar(s_new[i]);
}

int main(void)
{
    int nCase;
    scanf("%d", &nCase);
    while(nCase--){
        scanf("%d", &len);
        ; i<len; i++) scanf("%d", &s[i]);
        printf("%d\n", Manacher());
    }
    ;
}

HDU 3294

题意 : 首先给出一个字符,代表所有的字符真正对应的都往前移动,例如给出'b'那么真正的'a'就是'b','b'就是真正的'c',后来再给你一个串,问你通过上面转变后的最长回文子串是什么,给出首尾位置以及具体的回文序列

分析 : 这里多了一步需要具体定位回文,那么根据算法的具体意义,可以知道最长回文串的起始位置L=(i-p[i])/2,R=(i+p[i])/2-2,每一次更新答案都去更新L、R即可

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
;
];
], id, mx=;
int L, R; //回文串在原串的左右端点位置

int Init()
{
    int len = strlen(s);
    sNew[] = '$';
    sNew[] = '#';
    ;
    ; i < len; i++){
        sNew[j++] = s[i];
        sNew[j++] = '#';
    }
    sNew[j] = '\0';
    return j;
}

int Manacher()
{
    int len = Init();
    ;
    mx = ;
    ; i < len; i++){
         * id - i], mx - i);
        ;

        ///在对象不是字符串时候,原本为了防止越界是左有'$'
        ///右有'\0',现在右边就没有'\0',需要人为填充替代!

        while (sNew[i - p[i]] == sNew[i + p[i]]) p[i]++;

        if (mx < i + p[i]){
            id = i;
            mx = i + p[i];
        }

        //max_len = max(max_len, p[i] - 1);

////      如果题目不要求输出回文串在原串的位置,则用下面代码更新答案
        if(max_len < p[i]){ ///这里L、R记录的是最长回文子串在原串的左右端点
            max_len = p[i];
            L = (i - p[i])>>;
            R = (i + p[i] - )>>; ///R = (i + p[i])/2 -2;
        }

    }
    return max_len;

///    最后如若需要找到的回文串则是
///    for(int i=(id-mx+1);i<=(id+mx-1);i++)
///         if(sNew[i]!='#'&&sNew[i]!='$') ///注意你设置的开头符号和填充符号,不同则需要修改
///             putchar(sNew[i]);
}

];

int main(void)
{
    char letter;
    while(~scanf(" %c", &letter)){

        int num = letter - 'a';
        ; i<; i++)
            mp[(i+num)%] = i;

        scanf("%s", s);

        int len = strlen(s);
        ; i<len; i++) s[i] = mp[s[i]-'a']+'a';

        ){
            printf("%d %d\n", L, R);
            for(int i=L; i<=R; i++)
                 putchar(s[i]);
            puts("");
        }else puts("No solution!");
    }
    ;
}

Manacher模板( 线性求最长回文子串 )的更多相关文章

  1. manacher算法_求最长回文子串长度

    很好的总结,转自: http://blog.csdn.net/dyx404514/article/details/42061017 总结为:两大情况,三小情况. 两大情况:I. i <= p 1 ...

  2. manacher算法学习(求最长回文子串长度)

    Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...

  3. PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  4. hdu 3068 最长回文(manachar求最长回文子串)

    题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...

  5. [hdu3068 最长回文]Manacher算法,O(N)求最长回文子串

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文 ...

  6. Manacher算法 求 最长回文子串

    1 概述(扯淡) 在了解Manacher算法之前,我们得先知道什么是回文串和子串. 回文串,就是正着看反着看都一样的字符串.比如说"abba"就是一个回文串,"abbc& ...

  7. 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297

    1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...

  8. Manacher算法 O(n) 求最长回文子串

    转自:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧. ...

  9. Manacher算法——求最长回文子串

    首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...

随机推荐

  1. 操作系统安全 - 提权 - Windows提权 - 汇总

    CVE_2019-1388 Date: -- 影响范围: SERVER ====== Windows 2008r2 ** link OPENED AS SYSTEM ** Windows 2012r2 ...

  2. finereport 带多参数查询

    1.sql语句 ${,""," and dt.货主地区='"+comboBox0+"'")} ${,""," ...

  3. (转载)深入解析String#intern

    本文转载自:深入解析String#intern 引言 在 JAVA 语言中有8中基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念. ...

  4. redis学习(二)

    深入了解redis字符串,列表,散列和有序集合命令,了解发布,订阅命令和其他命令.   一,字符串   1.字符串可以存储3种类型的值 字符串,整数,浮点数 2.运算命令列表 incr : incr ...

  5. python+selenium上传文件——input标签

    我们要区分出上传按钮的种类,大体上可以分为两种: 第一种普通上传:将本地文件路径作为一个值,放在input标签中,通过form表单将这个值提交给服务器: 第二种插件上传:是通过Flash.JavaSc ...

  6. OSPF与ACL 综合应用

    1.企业内网运行OSPF路由协议,区域规划如图所示:2.财务和研发所在的区域不受其他区域链路不稳定性影响:3.R1.R2.R3只允许被IT登录管理:4.YF和CW之间不能互通,但都可以与IT互通:5. ...

  7. P1012拼数

    这是一道字符串的普及—的题. 输入几组数字,怎样组合起来才可以使最后结果最大.一开始这道题类似于那道删数问题,每次删除递增序列的最后一位,达到最小.而这个题我也是想到了贪心做法,于是想逐位判断,让在前 ...

  8. C++代码审查

    C++代码审查 1. 目的与要求 寻找结对编程伙伴,并练习结对编程: 对同伴的作品进行代码复审,设计审查表并填写: 评价同伴的代码,介绍同伴的优缺点. 2. 复审代码 小伙伴李宏达的项目代码与博客地址 ...

  9. oracle系统视图SQL语句整理

    -- DBA/ALL/USER/V_$/GV_$/SESSION/INDEX开头的绝大部分都是视图 -- DBA_TABLES意为DBA拥有的或可以访问的所有的关系表. -- ALL_TABLES意为 ...

  10. 出现( linker command failed with exit code 1)错误总结(http://blog.csdn.net/hengshujiyi/article/details/21182813)

    这种问题,通常出现在添加第三方库文件或者多人开发时. 这种问题一般是找不到文件而导致的链接错误. 我们可以从如下几个方面着手排查. 1.以如下错误为例,如果是多人开发,你同步完成后发现出现如下的错误. ...