洛谷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;
}
转载于:https://www.cnblogs.com/zwfymqz/p/10373538.html
洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)相关推荐
- [国家集训队]最长双回文串 manacher
---题面--- 题解: 首先有一个直观的想法,如果我们可以求出对于位置i的最长后缀回文串和最长前缀回文串,那么我们枚举分界点然后合并前缀和后缀不就可以得到答案了么? 所以我们的目标就是求出这两个数列 ...
- bzoj 2565: 最长双回文串 manacher算法
2565: 最长双回文串 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem. ...
- P4555-[国家集训队]最长双回文串【Manacher】
正题 题目链接:https://www.luogu.com.cn/problem/P4555 题目大意 长度为nnn的串,双回文串的定义是两个连续的回文串,求最长的双回文串. 解题思路 我们用马拉车维 ...
- BZOJ 2565 最长双回文串 Manacher
题目大意: 定义双回文串G是指一个可以被拆分成两个部分(S和T)的字符串G = S + T, 且S和T都是回文串的串, G自己本身可以不是回文串 给出一个长度为n ( 2 <= n <= ...
- 【BZOJ2565】最长双回文串 Manacher
题解: 首先我们写一个Manacher模板.. 然后我们可以把所有回文串的信息映射到左端点上, 每个点依此维护最长右连接回文串. 然后再顺着扫一遍就出解了. 代码: #include <cstd ...
- BZOJ 2565: 最长双回文串
2565: 最长双回文串 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1769 Solved: 895 [Submit][Status][Dis ...
- 青橙 A1280. 最长双回文串
A1280. 最长双回文串 时间限制:2.0s 内存限制:512.0MB 总提交次数: AC次数: 平均分: 将本题分享到: 查看未格式化的试题 提交 试题讨论 试题来源 中国 ...
- 【BZOJ2565】最长双回文串(回文树)
[BZOJ2565]最长双回文串(回文树) 题面 BZOJ 题解 枚举断点\(i\) 显然的,我们要求的就是以\(i\)结尾的最长回文后缀的长度 再加上以\(i+1\)开头的最长回文前缀的长度 至于最 ...
- HYSBZ 2565 最长双回文串 (回文树)
2565: 最长双回文串 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1377 Solved: 714 [Submit][Status][Dis ...
最新文章
- Spring Cloud Alibaba:Sentinel 热点参数限流
- Qt组件中的双缓冲无闪烁绘图
- 图解TCPIP-TCP IP
- AndroidAnnotations说明—AndroidAnnotations它是如何工作的?
- pandas知识点(汇总和计算描述统计)
- Repeater OnItemCommand 失效
- ajax是异步非阻塞,[转帖]再谈IO的异步,同步,阻塞和非阻塞
- 滤波笔记四:扩展卡尔曼滤波
- Android微信授权登录
- 单龙芯3A3000-7A1000PMON研究学习-(23)撸起袖子干-分析代码前的准备工作5
- 揭示世界本质的「机器科学家」,比深度神经网络还强?
- d-ary heaps 多叉树堆排序C++实现
- Java mail Exchange Service
- pcf8574c语言测试程序,51单片机+PCF8574简易密码锁程序 带详细注释 1602显示
- 取汉字拼音首字母--生成不重复ID(汉字--拼音--首字母)
- 涨知识!芯片是怎么做出来的,今天终于看懂了
- 第 1 天|基于 AI 进行游戏开发:5 天创建一个农场游戏!
- iview解决打包后icon不显示问题
- [C++]C++中的延时方法总结
- maven-springmvc工程