【做题】BZOJ2342 双倍回文——马拉车&并查集
题意:有一个长度为\(n\)的字符串,求它最长的子串\(s\)满足\(s\)是长度为4的倍数的回文串,且它的前半部分和后半部分都是回文串。
\(n \leq 5 \times 10^5\)
首先,显然要用manacher求出以每一位为中心的最长回文串。考虑枚举\(s\)最中间的一个位置\(i\),且以其为中心的最长回文串长度为\(2 r_i\),那么,前半部分的中心\(j\)就必须在\([i - \lfloor \frac {r_i} {2} \rfloor,i)\)的区间上,并且\(i - j \leq r_j\)。当然,我们会贪心地选择这个区间上最左边的合法的\(j\)。并且,只要某个\(j\)在当前中心为\(i\)的时候满足\(i - j \leq r_j\),那么,对于所有\(k \leq i\),都有\(k - j \leq r_j\)。
于是,只要从左往右移动\(i\),每次删除移动后非法的\(j\),问题就变成实现一个数据结构,支持:
- 删除一个元素
- 求一个值后继
这可以轻易地以\(O(n \log n)\)的时间复杂度实现,但我们希望一个更优的算法。
考虑一个元素如果每删除了,那么受影响的就只有以它为后继的值。这些值的后继会变成它们后继的后继。设\(S_i\)表示以元素\(i\)为后继的所有值的集合,那么,删除\(i\)后,我们只要把\(S_i\)合并到\(S_j\)里面就可以了。(元素\(j\)是元素\(i\)的后继)
因此,我们用并查集维护一下就好了。这个巧妙的技巧应该会在本题卡常时发挥作用。
时间复杂度\(O(n \alpha(n))\)
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
int n,len[N * 2],r[N];
char s[N];
void manacher() {
for (int i = 2 ; i <= (n << 1) ; ++ i) {
int l = i >> 1, r = (i + 1) >> 1;
while (s[l - len[i]] == s[r + len[i]] && l - len[i] >= 1 && r + len[i] <= n)
++ len[i];
l = i - 1, r = i + 1;
while ((l >> 1) - len[l] > (i >> 1) - len[i] && l >= 1 && r <= 2 * n)
len[r++] = len[l--];
len[r] = ((i + 1) >> 1) + len[i] - ((r + 1) >> 1);
i = r - 1;
}
}
int uni[N],ans;
vector<int> vec[N];
int getfa(int pos) {
return pos == uni[pos] ? pos : uni[pos] = getfa(uni[pos]);
}
int main() {
scanf("%d",&n);
scanf("%s",s+1);
manacher();
for (int i = 1 ; i <= n ; ++ i)
r[i] = len[i << 1 | 1];
for (int i = 1 ; i <= n ; ++ i)
uni[i] = i;
for (int i = 1 ; i < n ; ++ i) {
int k = i - (r[i] >> 1);
ans = max(ans,4 * (i - getfa(k)));
vec[i + r[i]].push_back(i);
for (int j = 0 ; j < (int)vec[i].size() ; ++ j)
uni[vec[i][j]] = vec[i][j] + 1;
}
printf("%d\n",ans);
return 0;
}
小结:对一些简单的小技巧还是不熟悉。或许是平庸的大数据结构做多了的问题吧。做题策略要调整。
【做题】BZOJ2342 双倍回文——马拉车&并查集的更多相关文章
- 【BZOJ-2342】双倍回文 Manacher + 并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1799 Solved: 671[Submit][Statu ...
- BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1123 Solved: 408 题目连接 http://w ...
- [BZOJ2342]双倍回文
对每个大中心暴力找小中心即可. 代码: #include<iostream> #include<cstdio> #include<cstring> #define ...
- bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)
https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...
- 【BZOJ2342】双倍回文(回文树)
[BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...
- BZOJ2342:[SHOI2011]双倍回文
浅谈\(Manacher\):https://www.cnblogs.com/AKMer/p/10431603.html 题目传送门:https://www.lydsy.com/JudgeOnline ...
- 【洛谷4287】[SHOI2011] 双倍回文(Manacher算法经典题)
点此看题面 大致题意: 求一个字符串中有多少个长度为偶数的回文串,它的一半也是回文串. \(Manacher\)算法 这应该是\(Manacher\)算法一道比较好的入门题,强烈建议在做这题之前先去学 ...
- BZOJ2342 Shoi2011 双倍回文 【Manacher】
BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...
- BZOJ2342: [Shoi2011]双倍回文
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 923 Solved: 317[Submit][Status ...
随机推荐
- Unity shader学习之标准的Unity shader
包含光照,可处理多个光源,有光照衰减和阴影的shader,代码如下: 转载请注明出处:http://www.cnblogs.com/jietian331/p/7199311.html Shader & ...
- GE与POST方法区别
1.用途. GET方法一般用于查询并获取信息,这意味着它是幂等的(对同一个url的多个请求,返回结果完全一样),因为没有修改资源状态,所以它是安全的.而POST一般用于更新资源信息,既不是幂等,也不是 ...
- windows编程之Windows Shell 编程
参考书<VC++ Windows Shell Programming> 这里仅仅是记录下该资源,推荐到下文列出的连接进行查看 用VC++ 进行Windows Shell 扩展编成 ...
- python windows环境下安装
下载python安装包,双击安装后, 在cmd中输入python 若无反应, 在cmd设置环境变量 变量 : set PATH=C:\...\...\...[python的编译器的路径]:%PATH% ...
- 【转】LoadRunner--Analysis各项指标详解
转载:https://blog.csdn.net/liangfengchang/article/details/45070321 一.常用到的性能测试术语1.事务(Transaction) 在web性 ...
- 20155228 2017-5-31 课堂测试:编写MyOD.java
20155228 2017-5-31 课堂测试:编写MyOD.java 题目和要求 编写MyOD.java:用java MyOD XXX实现Linux下od -tx -tc XXX的功能 提交测试代码 ...
- linux环境下tab键自动缩进4个空格
1. 进入 root 模式 su root 2. 编辑 /etc/vimrc 文件 root@localhost /home/xiluhua/tscripts $ vi /etc/vimrc 3. 文 ...
- 利用sqoop将hive数据导入导出数据到mysql
一.导入导出数据库常用命令语句 1)列出mysql数据库中的所有数据库命令 # sqoop list-databases --connect jdbc:mysql://localhost:3306 ...
- HashMap集合存储自定义类
第一种情况,key为String,value为自定义类person类: 输出结果,key重复的被去掉了,key重复的那个value值之前的被最后一个覆盖了: 第二种情况,key为自定义类person类 ...
- AtCoder Beginner Contest 086 (ABCD)
A - Product 题目链接:https://abc086.contest.atcoder.jp/tasks/abc086_a Time limit : 2sec / Memory limit : ...