洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)
题意
Sol
我的做法比较naive。。首先manacher预处理出以每个位置为中心的回文串的长度。然后枚举一个中间位置,现在要考虑的就是能覆盖到i - 1的回文串中 中心最靠左的,和能覆盖到i+1中 中心最靠右的,算一下答案取个max。
线段树维护一下区间min, max。标记永久化炒鸡好写
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;
char s[MAXN];
int len[MAXN], N, ans[MAXN];
template<typename A, typename B> inline void chmax(A &x, B y) {
x = x < y ? y : x;
}
template<typename A, typename B> inline void chmin(A &x, B y) {
x = x < y ? x : y;
}
int root, ls[MAXN], rs[MAXN], mn[MAXN], mx[MAXN], tot;
void Max(int &k, int l, int r, int ql, int qr, int v) {
if(!k) k = ++tot, mn[k] = INF;
if(ql <= l && r <= qr) {chmax(mx[k], v); return ;}
int mid = l + r >> 1;
if(ql <= mid) Max(ls[k], l, mid, ql, qr, v);
if(qr > mid) Max(rs[k], mid + 1, r, ql, qr, v);
}
void Min(int &k, int l, int r, int ql, int qr, int v) {
if(!k) k = ++tot, mn[k] = INF;
if(ql <= l && r <= qr) {chmin(mn[k], v); return ;}
int mid = l + r >> 1;
if(ql <= mid) Min(ls[k], l, mid, ql, qr, v);
if(qr > mid) Min(rs[k], mid + 1, r, ql, qr, v);
}
int QueryMx(int k, int l, int r, int p) {
int ans = mx[k];
if(l == r) return ans;
int mid = l + r >> 1;
if(p <= mid) chmax(ans, QueryMx(ls[k], l, mid, p));
else chmax(ans, QueryMx(rs[k], mid + 1, r, p));
return ans;
}
int QueryMn(int k, int l, int r, int p) {
int ans = mn[k];
if(l == r) return ans;
int mid = l + r >> 1;
if(p <= mid) chmin(ans, QueryMn(ls[k], l, mid, p));
else chmin(ans, QueryMn(rs[k], mid + 1, r, p));
return ans;
}
void trans() {
static char tmp[MAXN];
for(int i = 1; i <= N; i++) {
tmp[2 * i - 1] = s[i];
tmp[2 * i] = '#';
}
memcpy(s, tmp, sizeof(s));
N = (N << 1) - 1;
int mx = 0, id = 0;
for(int i = 1; i <= N; i++) {
ans[i] = (mx > i ? min(mx - i, ans[id * 2 - i]) : 1);
while(s[i - ans[i]] == s[i + ans[i]]) ans[i]++;
if(i + ans[i] > mx) mx = i + ans[i], id = i;
Max(root, 1, N, i - ans[i] + 1, i, i);
Min(root, 1, N, i, i + ans[i] - 1, i);
}
}
int main() {
scanf("%s", s + 1);
N = strlen(s + 1);
trans();
int ans = 0;
for(int i = 2; i <= N; i += 2) {
chmax(ans, (i - 1 - QueryMn(root, 1, N, i - 1)) + 1 + (QueryMx(root, 1, N, i + 1) - i - 1) + 1);
}
cout << ans;
return 0;
}
洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)的更多相关文章
- 洛谷 P4555 [国家集训队]最长双回文串 解题报告
P4555 [国家集训队]最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为\(n\)的串 ...
- 洛谷 P4555 [国家集训队]最长双回文串(Manacher)
题目链接:https://www.luogu.com.cn/problem/P4555 首先明白两个回文串,那么要使两个回文串成立,那么我们只能把$'#'$作为中间节点. 然后我们跑一边Manache ...
- 洛谷 P4555 [国家集训队]最长双回文串
链接: P4555 题意: 在字符串 \(S\) 中找出两个相邻非空回文串,并使它们长度之和最大. 分析: 直接使用马拉车算法求出每个点扩展的回文串.如果枚举两个回文串显然会超时,我们考虑切割一个长串 ...
- P4555 [国家集训队]最长双回文串
P4555 [国家集训队]最长双回文串 manacher 用manacher在处理时顺便把以某点开头/结尾的最长回文串的长度也处理掉. 然后枚举. #include<iostream> # ...
- 【洛谷】P4555 [国家集训队]最长双回文串
P4555 [国家集训队]最长双回文串 题源:https://www.luogu.com.cn/problem/P4555 原理:Manacher 还真比KMP好理解 解决最长回文串问题 转化为长度为 ...
- Manacher || P4555 [国家集训队]最长双回文串 || BZOJ 2565: 最长双回文串
题面:P4555 [国家集训队]最长双回文串 题解:就.就考察马拉车的理解 在原始马拉车的基础上多维护个P[i].Q[i]数组,分别表示以i结尾最长回文子串的长度和以i开头的最长回文子串的长度 然后就 ...
- BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)
BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...
- [国家集训队]最长双回文串 manacher
---题面--- 题解: 首先有一个直观的想法,如果我们可以求出对于位置i的最长后缀回文串和最长前缀回文串,那么我们枚举分界点然后合并前缀和后缀不就可以得到答案了么? 所以我们的目标就是求出这两个数列 ...
- P4555 [国家集训队]最长双回文串(回文树)
题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...
随机推荐
- cad.net 更改高版本填充交互方式为低版本样子
/// <summary> /// 修改cui,双击填充 /// </summary> /// https://blog.csdn.net/hfmwu/article/deta ...
- 一篇入门 -- Git
一. Git 介绍 Git作为一款分布式的==版本控制==工具,作为一名程序员,是必须要掌握的. 最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布.最初目的是为更好地 ...
- spark中RDD的transformation&action
简介: 1,transformation是得到一个新的RDD,方式很多,比如从数据源生成一个新的RDD,从RDD生成一个新的RDD 2,action是得到一个值,或者一个结果(直接将RDDcache到 ...
- JavaScript中JSON对象和JSON字符串的相互转化
一.JSON字符串转换为JSON对象 var str = '{"name":"cxh","sex":"man",&quo ...
- AndroidStudio项目制作倒计时模块
前言 大家好,给大家带来AndroidStudio项目制作倒计时模块的概述,希望你们喜欢 项目难度 AndroidStudio项目制作倒计时模块的难度,不是很大,就是主要用了Timer和TimerTa ...
- [git] 基本原理
1. 基本原理 工作目录:本地项目所在目录 暂存区: 被 git 所管理的文件 本地仓库:本地的版本仓库,一般的提交操作会将变更信息先提交到本地仓库的版本库中 远程仓库:远程的版本仓库,将变更信 ...
- python库函数Map, Filter and Reduce的用法
python中有三个函数式编程极大的简化了程序的复杂性,这里就做一下讨论和记录. 一 Map:应用在链表输入所有元素的函数,它的格式如下所示: map(function_to_apply, list_ ...
- git关于文件权限修改引起的冲突及忽略文件权限的办法
我们在使用git进行版本管理的时候,有时候只是修改了文件的权限,比如将pack.php修改为777,但其实文件内容并没有改变,但是git会认为此文件做了修改,原因是git把文件权限也算作文件差异的一部 ...
- Alienware-15-R3 装Ubuntu 16.04.3 LTS
前言:Alienware-15-R3默认安装的系统是win10.现在卸载win0,装Ubuntu 16.04.3 LTS. 一.下载Ubuntu 16.04.3 LTS镜像文件,下载地址:https: ...
- java中Memcache的使用
java中Memcache的使用 一.什么是Memcached? Memcached是danga.com开发的分布式内存对象缓存系统,所谓分布式,意味着它不是本地的,而是基于网络连接完成服务.Memc ...