洛谷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 ,即可 ...
随机推荐
- Ubuntu 16.04虚拟机调整窗口大小自适应Windows 7
Windows 7上Ubuntu 16.04虚拟机安装成功后,默认的虚拟机窗口比较小,需要适当调整,才能把虚拟机的屏幕放大, 适合使用,以下介绍调整方法. 安装VMware Tools 启动虚拟机, ...
- 3.复杂的viewpager
实现这样的效果: 1.主页面布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quo ...
- Android开发工程师文集-1 小时学会SQLite
前言 大家好,给大家带来Android开发工程师文集-1 小时学会SQLite的概述,希望你们喜欢 内容 什么是Sqlite: 效率高,开源,小型,程序驱动,支持事务操作,无数据类型,可嵌入的关系型数 ...
- Linux 后台运行命令:nohup 和 &
[参开文章]:nohup 与 & 的区别 1. nohup 1.1 基本概念 将程序以忽略挂起信号的方式运行起来: 不可以免疫 Ctrl + C 的 SIGINT 中断信号: 可以免疫 SI ...
- python 离散序列 样本数伸缩(原创)
解决问题: 有一个固定长度的1维矩阵,将这个矩阵的取样点进行扩充和减少 功能函数: def discrete_scale(data, num): import numpy as np import c ...
- .NET 构造DataTable返回多个json值
有时候我们使用Ajax链接一般处理程序需要返回多个值,然而这些数据并非在一个查询表内,此时便想到构造一个虚拟的DataTable,这样就可以返回多个值了(当然有很多办法,这是其中一种 ). 首先我们需 ...
- conda环境里安装pydot
一.conda环境里安装pydot, 输入以下命令即可: conda install -c anaconda pydot 二.如果运行tensorflow,提示缺什么包,都可以在这里下载. ----- ...
- 【DB2】Event monitor for locking
Customer said, they got the following Errors in applications logs Caused by: financing.tools.hub.sha ...
- 一个关于margin-top的问题
两个 此时内部div的样式为 当我把margin选中 如图所示: 我想要的效果是子div离父div有一个20px的间隙,但显然现在不是我想要的结果, 然后就开始查资料: 这个“问题”……它是CSS2. ...
- 移动端真机调试终极利器-BrowserSync(使用方法)
1. 安装 Node.js BrowserSync是基于Node.js的, 是一个Node模块, 如果您想要快速使用它,也许您需要先安装一下Node.js 安装适用于Mac OS,Windows和Li ...