Description

题库链接

记一个字符串为 \(X\) ,它的倒置为 \(X^R\) 。现在给你一个长度为 \(n\) 的字符串 \(S\) ,询问其最长的形同 \(XX^RXX^R\) 的子串长度为多少。

\(1\leq n\leq 500000\)

Solution

显然求回文之类的东西还是要 \(manacher\) 的。

假设我们求出了 \(manacher\) 的 \(len\) 数组,考虑怎么去用这个 \(len\) 。

值得肯定的是我们可以用 \(len\) 来刻画“双倍回文”。对于双倍回文的中点 \(x\) ,考虑记其第三段为 \((x,y-1)\) 。

显然我们可以去枚举 \(x\) ,然后去找离 \(x\) 最远的 \(y\) 。

我们可以用不等式 \(\begin{cases} \begin{aligned} x &\geq y-len_y \\ y &\leq x+\frac{len_x}{2} \end{aligned} \end{cases}\) 来刻画一对 \((x,y)\) 。

现在就变成了枚举 \(x\) 然后去找一个满足上述情况对应的最大的 \(y\) 。

排序+ \(set\) 维护即可。

Code

//It is made by Awson on 2018.3.16
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 500000;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); } int n, loc, len[(N<<1)+5], f[N+5];
char s[N+5], ch[(N<<1)+5];
struct tt {
int id, x;
bool operator < (const tt &b) const {return id-x < b.id-b.x; }
}a[N+5];
set<int>S; void work() {
read(n); scanf("%s", s+1);
for (int i = 1; i <= n; i++) ch[++loc] = '#', ch[++loc] = s[i];
ch[++loc] = '#', ch[++loc] = '$';
int mx = 0, po = 0;
for (int i = 1; i <= loc; i++) {
if (mx > i) len[i] = Min(len[(po<<1)-i], mx-i);
else len[i] = 1;
while (ch[i+len[i]] == ch[i-len[i]]) ++len[i];
if (i+len[i] > mx) mx = i+len[i], po = i;
}
for (int i = 1; i <= n; i++) f[i] = a[i].x = ((len[(i<<1)+1]-1)>>1), a[i].id = i;
sort(a+1, a+n+1); loc = 1; int ans = 0;
for (int i = 1; i <= n; i++) {
while (loc <= n && a[loc].id-a[loc].x <= i) S.insert(a[loc].id), ++loc;
set<int>::iterator it = S.upper_bound(i+(f[i]>>1));
if (it == S.begin()) continue;
int t = *(--it)-i; ans = Max(ans, t);
}
writeln(ans<<2);
}
int main() {
work(); return 0;
}

[SHOI 2011]双倍回文的更多相关文章

  1. 「BZOJ 2342」「SHOI 2011」双倍回文「Manacher」

    题意 记\(s_R\)为\(s\)翻转后的串,求一个串最长的形如\(ss_Rss_R\)的子串长度 题解 这有一个复杂度明显\(O(n)\)的做法,思路来自网上某篇博客 一个双倍回文串肯定当且仅当本身 ...

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

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

  3. BZOJ 2342 双倍回文(manacher算法)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2342 题意:定义双倍回文串为:串的长度为4的倍数且串的前一半.后一半.串本身均是回文的. ...

  4. BZOJ2342: [Shoi2011]双倍回文

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

  5. 【BZOJ2342】双倍回文(回文树)

    [BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...

  6. [SHOI2011]双倍回文

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

  7. BZOJ2342[Shoi2011]双倍回文——回文自动机

    题目描述 输入 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. 输出 输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文 ...

  8. bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...

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

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

随机推荐

  1. 计算1-1/3+1/5-1/7+···的前n项和

    这图1为书里的教材,图二为自己打的程序 (1)二者相比,自己写的代码显得更短,听说代码写的越精简越好,但是自己的较难分析,他人看来可能会较难理解一点:(自己在第一次运行时将for()中的第二个表达式写 ...

  2. JavaScript(第三十天)【XPath】

    XPath是一种节点查找手段,对比之前使用标准DOM去查找XML中的节点方式,大大降低了查找难度,方便开发者使用.但是,DOM3级以前的标准并没有就XPath做出规范:直到DOM3在首次推荐到标准规范 ...

  3. css代码整理

    width:(宽度) height:(高度) border:1px solid red:(边框 :边框粗细 显示 颜色) border-radius:10deg:(边框变圆角) box-shadow: ...

  4. Scrum 冲刺 第一日

    Scrum 冲刺 第一日 站立式会议 燃尽图 Alpha 阶段认领任务 明日任务安排 项目预期任务量 成员贡献值计算规则 今日贡献量 参考资料 站立式会议 返回目录 燃尽图 返回目录 Alpha 阶段 ...

  5. new malloc和delete free 的区别

    今天看了一个面试题:问new 和 malloc, delete 和 free 的区别,扭捏了半天,也没说完全:现总结如下: 1.先看看new 和 delete 看一个例子: <span styl ...

  6. CNN中的padding

    在使用TF搭建CNN的过程中,卷积的操作如下 convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], padding="SAME& ...

  7. babel基本用法

    babel-cli babel-cli是本地使用编译js文件 1.安装: cnpm i babel-cli babel-preset-env -D 2.配置packjson: "script ...

  8. Win7添加php环境变量.

    1) "我的电脑"右键"属性"->高级系统设置->环境变量->系统变量->Path->编辑 2) 将PHP的执行路径的目录&quo ...

  9. js 过多 导致页面加载过慢

    自己的代码检查了很久,才检查 出来 通常我们的网站里面会加载一些js代码,统计啊,google广告啊,百度同盟啊,阿里妈妈广告代码啊, 一堆,最后弄得页面加载速度很慢,很慢. 解决办法:换一个js包含 ...

  10. Python内置函数(14)——bytes

    英文文档: class bytes([source[, encoding[, errors]]]) Return a new "bytes" object, which is an ...