BZOJ2342 Manacher + set
题一:别人介绍的一道题,题意是给出一个序列,我们要求出一段最常的连续子序列,满足:该子序列能够被平分为三段,第一段和第二段形成回文串,第二段和第三段形成回文串。
题二:BZOJ2342和这题非常的相似,BZOJ的题意是说求出一个最长的回文串,该串能平均分四段,满足整体是回文串,前一半是回文串,后一半也是回文串。
对于第一个问题的做法是:Manacher后,枚举每一个位置i(一定是#),作为第二个中心,那么我们就需要在[i-Mp[i], i]之间找到一个最小的j,满足以j为中心的回文串能够覆盖到位置i, 最先找到的,贡献的答案肯定最大。是不是对于每个位置i,我们都需要在前面找所有的范围内的j呢? jiaru摸个j形成的回文不能覆盖到i, 那么这个j肯定不能覆盖到k(k>i), 即这个j对之后的位置都没有贡献,可以删除, 而每个位置最多被删一次, 复杂度为nlog
题二:
/**************************************************************
Problem: 2342
User: foratrp
Language: C++
Result: Accepted
Time:748 ms
Memory:18280 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#include <stack>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int N = 5e5 + ; char Ma[N <<];
int Mp[N << ];
char s[N]; void Manacher(int len) {
int l = ;
Ma[l++] = '$';
Ma[l++] = '#';
for(int i = ; i < len; ++i)
{
Ma[l++] = s[i];
Ma[l++] = '#';
}
Ma[l] = ;
int mx = , id = ;
for(int i = ; i < l; ++i)
{
Mp[i] = mx > i ? min(Mp[ * id - i], mx - i) : ;
while (Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i]++;
if(i + Mp[i] > mx) mx = i + Mp[i], id = i;
}
// for(int i = 0; i < l; ++i) printf("%d ", Mp[i]);
}
set<int> ms;
void solve(int n) {
int ans = ; ms.clear();
for(int i = ; i < * n + ; i += ) ms.insert(i);
for(int i = ; i < * n + ; i += )
{
int j = i - (Mp[i] / );
if(j % == ) j++;
while(j != i)
{
if(j + Mp[j] > i) { ans = max(ans, (i - j) * ); break; }
else { ms.erase(j); j = *ms.lower_bound(j); }
}
}
printf("%d\n", ans);
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif
int len;
while(~scanf("%d", &len)) {
scanf("%s", s);
Manacher(len);
solve(len);
}
return ;
}
题一:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#include <stack>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int N = 5e5 + ; int Ma[N <<];
int Mp[N << ];
int s[N]; void Manacher(int len) {
int l = ;
Ma[l++] = -INF;
Ma[l++] = INF;
for(int i = ; i < len; ++i)
{
Ma[l++] = s[i];
Ma[l++] = INF;
}
Ma[l] = ;
int mx = , id = ;
for(int i = ; i < l; ++i)
{
Mp[i] = mx > i ? min(Mp[ * id - i], mx - i) : ;
while (Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i]++;
if(i + Mp[i] > mx) mx = i + Mp[i], id = i;
}
//wwww for(int i = 0; i < l; ++i) printf("%d ", Mp[i]);
}
set<int> ms;
void solve(int n) {
int ans = ; ms.clear();
for(int i = ; i < * n + ; i += ) ms.insert(i);
for(int i = ; i < * n + ; i += )
{
int j = i - Mp[i] + ;
while(j != i)
{
if(j + Mp[j] > i) { ans = max(ans, (i - j) / * ); break; }
else { ms.erase(j); j = *ms.lower_bound(j); }
}
}
printf("%d\n", ans);
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif
int cas, _ = , len;
scanf("%d", &cas);
while(cas --) {
scanf("%d", &len);
for(int i = ; i < len; ++i) scanf("%d", &s[i]);
Manacher(len); printf("Case #%d: ", _++);
solve(len);
}
return ;
}
BZOJ2342 Manacher + set的更多相关文章
- BZOJ2342 Shoi2011 双倍回文 【Manacher】
BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...
- 【BZOJ2342】双倍回文(manacher,并查集)
题意: 思路:From http://blog.sina.com.cn/s/blog_8d5d2f04010196bh.html 首先我可以看出: (1)我们找到的串的本身也是一个回文串(显然) (2 ...
- 【BZOJ-2342】双倍回文 Manacher + 并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1799 Solved: 671[Submit][Statu ...
- BZOJ2342:[SHOI2011]双倍回文(Manacher)
Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输出文件只有一行,即:输入数据中字符串的最长 ...
- [BZOJ2342] [Shoi2011]双倍回文(manacher)
传送门 manacher...... 先跑一边manacher是必须的 然后枚举双倍回文串的对称轴x 把这个双倍回文串分成4段,w wR w wR 发现,只有当 y <= x + p[x] / ...
- HDU3068 回文串 Manacher算法
好久没有刷题了,虽然参加过ACM,但是始终没有融会贯通,没有学个彻底.我干啥都是半吊子,一瓶子不满半瓶子晃荡. 就连简单的Manacher算法我也没有刷过,常常为岁月蹉跎而感到后悔. 问题描述 给定一 ...
- manacher算法专题
一.模板 算法解析:http://www.felix021.com/blog/read.php?2040 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为 ...
- lintcode最长回文子串(Manacher算法)
题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...
- Manacher's algorithm
Manacher's algorithm 以\(O(n)\)的线性时间求一个字符串的最大回文子串. 1. 预处理 一个最棘手的问题是需要考虑最长回文子串的长度为奇数和偶数的情况.我们通过在任意两个字符 ...
随机推荐
- linux -目录结构
摘自:http://www.comptechdoc.org/os/linux/usersguide/linux_ugfilestruct.html 这个目录结构介绍是我目前看到介绍最全的,有时间在翻译 ...
- Java与各种数据库连接代码
6.MySQL数据库Class.forName("org.gjt.mm.mysql.Driver").newInstance();String url ="jdbc:my ...
- word20161216
object / 对象 object identifier / 对象标识符 offline / 脱机 OLE on-disk catalog / 磁盘目录 on-media catalog / 媒体 ...
- 共享MFC dULL
>------ 已启动生成: 项目: OSGtest, 配置: Debug Win32 ------1>正在编译...1>AddScene.cpp1>main.cpp1> ...
- Appium 三种wait方法(appium 学习之改造轮子)
前些日子,配置好了appium测试环境,至于环境怎么搭建,参考:http://www.cnblogs.com/tobecrazy/p/4562199.html 知乎Android客户端登陆:htt ...
- Python之Web框架Django
Python之Web框架: Django 一. Django Django是一个卓越的新一代Web框架 Django的处理流程 1. 下载地址 Python 下载地址:https://www.pyt ...
- Python之路,Day5 - Python基础5
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 一.列表生成器 , 1, 2, 3, 4, 5, 6, 7, 8, 9 ...
- Alipay秘钥问题
有三种秘钥一个是应用公钥 一个是支付宝公钥 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco } span.s1 { text-d ...
- HTML5 绘制简单圆形 loading. . . .
现在有很多的 loading 组件 什么js 等等 闲来没事就写一个 H5的 loading 有很多的Loading 是一张张图片 js 控制的 有了 canvas的 出现 你就可以体验不同之处了 ...
- iOS - 如何切图适配各种机型
关于iPhone6/6+适配问题一直有争议,今天小编专门为大家整理了相关的有效方案,希望对大伙儿有帮助! 移动app开发中多种设备尺寸适配问题,过去只属于Android阵营的头疼事儿,只是很多设计师选 ...