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. (译文)JavaScript基础——JavaScript中的深拷贝

    在JavaScript中如何拷贝一个对象? 通过引用调用 function mutate(obj) { obj.a = true; } const obj = {a: false}; mutate(o ...

  2. [福大软工] W班 软件产品案例分析

    作业要求 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/1300 评分细则 第一部分 调研,评测 (3 ...

  3. Beta阶段敏捷冲刺每日报告——Day0

    下一阶段需要改进完善的功能: 搜索框在Firefox和IE中显示不正常问题 下一阶段新增的功能: ToDoList功能:针对博主的功能,在博主登录之后可以添加和修改待办事项,每个事项包括标题.内容.日 ...

  4. 1013团队Beta冲刺day7

    项目进展 李明皇 今天解决的进度 部分数据传递和使用逻辑测试 林翔 今天解决的进度 服务器端查看个人发布的action,修改已发布消息状态的action,仍在尝试使用第三方云存储功能保存图片 孙敏铭 ...

  5. JAVA接口基础知识总结

    1:是用关键字interface定义的. 2:接口中包含的成员,最常见的有全局常量.抽象方法. 注意:接口中的成员都有固定的修饰符. 成员变量:public static final     成员方法 ...

  6. 使用Spark MLlib进行情感分析

    使用Spark MLlib进行情感分析             使用Spark MLlib进行情感分析 一.实验说明 在当今这个互联网时代,人们对于各种事情的舆论观点都散布在各种社交网络平台或新闻提要 ...

  7. VS2013 重装 无法打开项目

    今天遇到的奇葩BUG,耗时我一下午,现在跟大家说道说道. 今天重装系统,让各种开发环境开发工具自然要重装一次,最后装完VS2013,然后刚好客户打电话要改点东西,然后我就双击项目准备打开改,然后奇葩来 ...

  8. 新概念英语(1-141)Sally's first train ride

    Lesson 141 Sally's first train ride 萨莉第一交乘火车旅行 Listen to the tape then answer this question. Why was ...

  9. maven入门(9)Maven常用命令

    Maven常用命令 清理 clean编译 compile打包 package安装 install跳过测试 clean package -Dmaven.test.skip=true

  10. ssh_maven的搭建之dao层的开发

    之前都是使用我们传统的方式进行引入jar包,现在我们使用maven进行管理依赖,这样,我们的jar就不需要我们进行管理,而且,我们的maven还可以进行项目构建,一个项目从编写源代码到编译,测试,运行 ...