题面:

  洛谷:[SHOI2011]双倍回文‘

题解:

  首先有一个性质,本质不同的回文串最多O(n)个。

  所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间劈开后左边的一半是否也是一个回文串(判断左边那半的中点的回文半径是否可以跨过当前长串的中点)。

  复杂度O(n)

 // luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 1001000 int n, pos, maxn, ans;
int r[AC];
char a[AC], s[AC]; void pre(){
scanf("%d%s", &n, a + );
s[] = '$', s[] = '#';
for(R i = ; i <= n; i ++) s[ * i] = a[i], s[ * i + ] = '#';
} inline void upmax(int &a, int b){
if(b > a) a = b;
} void manacher()
{
int b = * n;
for(R i = ; i <= b; i ++)
{
r[i] = (maxn > i) ? min(r[ * pos - i], maxn - i + ) : ;//这里要取min
while(s[i - r[i]] == s[i + r[i]]) ++ r[i]; int last = i - r[i] + , Next = i + r[i] - ;
if(s[last] == '#') ++ last, -- Next;
if(i + r[i] - > maxn && last <= i)//last才是整个串的开头
{
for(R j = maxn + ; j <= Next; j ++)
{
int l = * i - j;//获取串头
int sum = (j - l + + ) >> ;
if(s[j] == '#' || sum % ) continue;//中间是获取实际字符数
int tmp = (l + j) >> , k = (tmp + l) >> ;
if(k + r[k] - >= tmp) upmax(ans, sum);
}
} if(i + r[i] - > maxn) pos = i, maxn = i + r[i] - ;
}
printf("%d\n", ans);
} int main()
{
//freopen("in.in", "r", stdin);
pre();
manacher();
//fclose(stdin);
return ;
}

[SHOI2011]双倍回文 manacher的更多相关文章

  1. bzoj 2342: [Shoi2011]双倍回文 -- manacher

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符 ...

  2. BZOJ2342:[SHOI2011]双倍回文(Manacher)

    Description   Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输出文件只有一行,即:输入数据中字符串的最长 ...

  3. [BZOJ2341][Shoi2011]双倍回文 manacher+std::set

    题目链接 发现双倍回文串一定是中心是#的回文串. 所以考虑枚举#点.发现以\(i\)为中心的双倍回文的左半部分是个回文串,其中心一定位于\(i-\frac{pal[i]-1}2\)到\(i-1\)之间 ...

  4. BZOJ 2342: [Shoi2011]双倍回文 [Manacher + set]

    题意: 求最长子串使得它有四个相同的回文串SSSS相连组成 枚举中间x 找右边的中间y满足 y-r[y]<=x y<=x+r[x]/2 用个set维护 注意中间只能是# #include ...

  5. BZOJ2342 Shoi2011 双倍回文 【Manacher】

    BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...

  6. Manacher || BZOJ 2342: [Shoi2011]双倍回文 || Luogu P4287 [SHOI2011]双倍回文

    题面:[SHOI2011]双倍回文 题解:具体实现时,就是在更新mr时维护前半段是回文串的最长回文串就好了 正确性的话,因为到i时如果i+RL[i]-1<=mr,那么答案肯定在i之前就维护过了: ...

  7. 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...

  8. 【BZOJ-2342】双倍回文 Manacher + 并查集

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1799  Solved: 671[Submit][Statu ...

  9. BZOJ2342: [Shoi2011]双倍回文

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 923  Solved: 317[Submit][Status ...

随机推荐

  1. Google Chrome插件分享

    前言 浏览器是大家日常使用最多的工具之一,对于程序员来说,Google Chrome浏览器当然是大家优选的最爱之一.面对Chrome丰富的插件真的是爱不释手,如何把自己的Chrome调教成自己心仪的样 ...

  2. gopherjs

    An example implementation of a GopherJS client and a Go server using the Improbable gRPC-Web impleme ...

  3. android点击事件的四种方式

    android点击事件的四种方式 第一种方式:创建内部类实现点击事件 代码如下: package com.example.dail; import android.text.TextUtils; im ...

  4. spark的运行方式——转载

    本文转载自:      spark的运行方式 本文主要讲述运行spark程序的几种方式,包括:本地测试.提交到集群运行.交互式运行 等. 在以下几种执行spark程序的方式中,都请注意master的设 ...

  5. oracle时间转换查询

    查询oracle 数据库时要查询某一字段的最大时间或者最小时间,因为oracle的时间点 精确到毫秒 甚至更高精度级别 根据字段来转换成对应的时间格式: SELECT TO_CHAR(MAX(crea ...

  6. 英文Datasheet没那么难读

    话说学好数理化,走遍天下都不怕.可是在这个所谓的全球化时代,真要走遍天下的话,数理化还真未必比得上一门外语.作为技术人员,可以看到的是目前多数前沿的产品和技术多来自发达的欧美等国家,而英语目前才是真正 ...

  7. LeetCode 36. Valid Sudoku (C++)

    题目: Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according t ...

  8. Scrum立会报告+燃尽图(十月十日总第一次):选题

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2190 Scrum立会master:付佳 一.小组介绍 组长:付佳 组员: ...

  9. pspo过程文档

    项目计划总结:       日期/任务      听课        编写程序         阅读相关书籍 日总计          周一      110          60         ...

  10. python __call__ 函数

    __call__ Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的. 换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符. ...