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. 预处理 一个最棘手的问题是需要考虑最长回文子串的长度为奇数和偶数的情况.我们通过在任意两个字符 ...
随机推荐
- 2.2、Hibernate用注解方式实现一对多、多对多关系
一.一对多关系 1.在上一篇日志中用.xml配置文件项目基础上,再往lib目录先添加一个包-hibernate-jpa-2.0-api-1.0.0.Final.jar 2.新建一个com.st.bea ...
- 有哪些经常被误用的 HTML、JavaScript、CSS 的元素、方法和属性?
一,以前想要把一个元素(input 之类的)设成只读的时候都是用 disabled,后来发现这是不对的. 因为在 HTML 里面,如果一个元素被设置成 disabled, 那么它的值就不会被发送到 s ...
- android 弹出AlertDialog的学习案例
我在编写的时候,测试的关键代码: AlertDialog.Builder builder=new AlertDialog.Builder(MainPointListActivity.this); bu ...
- js中typeof和instanceof
对于typeof和instanceof,我们经常用来检测数据的类型.typeof可以检测Number.Boolean.String.Undefined类型,对于其他类型的数据都返回为object:而i ...
- ubuntu下C++连接mysql数据库
参考了该博客的做法:http://zhmy.michael.blog.163.com/blog/static/861578792012101244715692/ 1.安装mysql: sudo apt ...
- js储存参数的数组arguments
js函数中有个储存参数的数组arguments ,所有函数获得的参数会被编译器挨个保存到这个数组中.于是我们的js版支持参数默认值的函数可以通过另外一种变通的方法实现 function simue ( ...
- Facebook的Web开发三板斧:React.js、Relay和GraphQL
2015-02-26 孙镜涛 InfoQ Eric Florenzano最近在自己的博客上发表了一篇题为<Facebook教我们如何构建网站>的文章,他认为软件开发有些时候需要比较大的跨 ...
- nginx中error_page没有生效(nginx+passenger+rails)
应用部署方式为 nginx + passenger + rails 当我想要用nginx来默认处理400以上状态时,发现在rails返回respose之后,nginx不会再次执行error_page( ...
- PPM图片格式及其C读写代码
PPM图像格式介绍 PPM图像格式是由Jef Poskanzer 大叔,在我出生那一年,也就是1991年所创造的,碰巧的是PPM也是天蝎座. PPM(Portable Pixmap Format)还有 ...
- MyBK