Manacher

c.

/*
Manacher模板
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

//求最长回文子串
const int MAXN=110010;
char Ma[MAXN*2];
int Mp[MAXN*2];

void Manacher(char s[],int len){
    int l=0;
    Ma[l++]=‘$‘;
    Ma[l++]=‘#‘;
    for(int i=0;i<len;i++){
        Ma[l++]=s[i];
        Ma[l++]=‘#‘;
    }
    Ma[l]=0;
    int mx=0,id=0;
    for(int i=0;i<l;i++){
        Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1;
        while(Ma[i+Mp[i]]==Ma[i-Mp[i]])Mp[i]++;
        if(i+Mp[i]>mx){
            mx=i+Mp[i];
            id=i;
        }
    }
}
/*
abaaba
i:    0 1 2 3 4 5 6 7 8 9 10 11 12 13
Ma[i]:$ # a # b # a # a # b  #  a  #
Mp[i]:1 1 2 1 4 1 2 7 2 1 4  1  2  1
*/

char s[MAXN];
int main(){
    while(scanf("%s",s)==1){
        int len=strlen(s);
        Manacher(s,len);
        int ans=0;
        for(int i=0;i<2*len+2;i++)
            ans=max(ans,Mp[i]-1);
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-08-06 07:50:11

Manacher的相关文章

BZOJ 2084 [Poi2010]Antisymmetry(manacher)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2084 [题目大意] 对于一个01字符串,如果将这个字符串0和1取反后, 再将整个串反过来和原串一样,就称作“反对称”字符串. 比如00001111和010101就是反对称的,1001就不是. 现在给出一个长度为N的01字符串,求它有多少个子串是反对称的. [题解] 修改manacher的判定条件,对该串进行计算即可. [代码] #include <cstdio> #include

HDU 3068 最长回文 (manacher算法)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9188    Accepted Submission(s): 3159 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

manacher马拉车算法

入门manacher最好文章:https://segmentfault.com/a/1190000003914228 我整理了模板代码:HDOJ3068马拉车模板 1 //讲解 https://segmentfault.com/a/1190000003914228 2 //manacher 算法模板 3 //求最长回文串 O(N) 4 #include <bits/stdc++.h> 5 using namespace std; 6 const int maxn=3e5+10; 7 char

HDU 4513 吉哥系列故事——完美队形II (Manacher变形)

题意:假设有n个人按顺序的身高分别是h[1], h[2] ... h[n],从中挑出一些人形成一个新的队形,新的队形若满足以下要求,则就是新的完美队形:  1.连续的 2.形成回文串 3.从左到中间那个人,身高需保证不下降 问有组成完美队形的最多人数 题解:Manacher算法的变形. 首先我们来解释一下Manacher算法:在我看来就是一个优化的暴力. 我们首先统一奇偶回文串成为奇数回文串,就是在两个数之间加入一些不可能出现的数. 例如题目:1 2 3 3 2 5 2 3 1—>(符号更加清楚

hdu5785--Interesting(manacher)

题意:求给定字符串的三元组(I,J,K)  使得S[i..j] 和 S[j+1..k] 都是回文串.求所有满足条件的三元组 ∑(i*k) 题解:求出以j为结尾的回文串起始位置的和记为lv[j],和以j+1为开始的回文串末位置的和rv[j+1] 答案就是∑[j:1-n](lv[j] * rv[j+1]) 因为…… (a+b+c....)*(x+y+z.....) = a*x + a*y + a*z + .... 看了题解之后才恍然大悟ˊ_>ˋ有多蠢 然后就是自己写的代码 一直wa,以为哪里没有取模

HDU5677 manacher + 二维多重背包

附上题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5677 问题描述 ztr喜欢研究子串,今天,他有n个串 现在ztr想知道,能否从这n个串的所有回文子串中, 取出恰好k个回文串且满足这些回文串的长度之和为L 以yjqqaq为例 这个串包含的回文子串有 y,j,q,a,q,qq,qaq 所以我们可以既选qq,又选qaq 输入描述 有T组数据,第一行为一个正整数T(T<=10)T(T<=10) 每组数据第一行为三个正整数N(1<=N<

HDU3068 manacher算法

附上题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068  这个题的意思是给你一个串, 求这个串中的最长的回文串的长度, 直接裸manacher即可. 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int maxn = 110000*2

manacher算法模板

char a[maxn]; int p[maxn]; //manacher void manacher(char *s){ int len = strlen(s+1); int m = 2*len+1; for(int i=1; i<=len; i++){ a[i<<1] = s[i]; a[i<<1|1] = '#'; } a[0] = '+'; a[1] = '#'; a[m+1] = '-'; // cout<<a<<endl; int mx=0

Girls&#39; research(manacher)

Girls' research Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1160    Accepted Submission(s): 448 Problem Description One day, sailormoon girls are so delighted that they intend to research a

吉哥系列故事——完美队形II---hdu4513(最长回文子串manacher)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4513 题意比最长回文串就多了一个前面的人要比后面的人低这个条件,所以在p[i]++的时候判断一下s[i-p[i]]<=s[i-p[i]+2]就可以了; 用最长回文串算法manacher:套一下模板就可以了: #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; con