题意:有一个长度为\(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 双倍回文——马拉车&并查集的更多相关文章

  1. 【BZOJ-2342】双倍回文 Manacher + 并查集

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1799  Solved: 671[Submit][Statu ...

  2. BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1123  Solved: 408 题目连接 http://w ...

  3. [BZOJ2342]双倍回文

    对每个大中心暴力找小中心即可. 代码: #include<iostream> #include<cstdio> #include<cstring> #define ...

  4. bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...

  5. 【BZOJ2342】双倍回文(回文树)

    [BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...

  6. BZOJ2342:[SHOI2011]双倍回文

    浅谈\(Manacher\):https://www.cnblogs.com/AKMer/p/10431603.html 题目传送门:https://www.lydsy.com/JudgeOnline ...

  7. 【洛谷4287】[SHOI2011] 双倍回文(Manacher算法经典题)

    点此看题面 大致题意: 求一个字符串中有多少个长度为偶数的回文串,它的一半也是回文串. \(Manacher\)算法 这应该是\(Manacher\)算法一道比较好的入门题,强烈建议在做这题之前先去学 ...

  8. BZOJ2342 Shoi2011 双倍回文 【Manacher】

    BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...

  9. BZOJ2342: [Shoi2011]双倍回文

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 923  Solved: 317[Submit][Status ...

随机推荐

  1. [17]Windows的启动过程

    一.内核的引导 在intel x86系统上,windows操作系统获得控制首先从硬盘的主引导记录(MBR,Master Boot Record)开始,windows setup程序在安装windows ...

  2. PID控制動手玩玩看

    PID控制動手玩玩看 PID三個參數到底該怎麼調才好,真的是一門藝術. 雖然在Marlin韌體內有提供自動測量的功能,但是測得的結果,不見得能令人滿意,還是需要調整.可是到底該怎麼調整?從哪個參數開始 ...

  3. 如何重置Sitecore CMS中的管理员密码

    在Sitecore项目上工作时,有时管理员凭据会丢失或损坏.在这些情况下,重新获得快速访问权限以便不中断开发非常重要. 对Core数据库运行以下查询,您将能够admin/b再次使用以下命令登录Site ...

  4. Windows 7关闭睡眠(休眠)模式和删除休眠文件

    原文地址:https://www.192ly.com/pc/win7/gb-sm.html 怎么关闭Windows 7关闭睡眠(休眠)功能?Windows 7系统中怎么删除休眠文件?Windows 7 ...

  5. CATALINA_OPTS和 JAVA_OPTS区别

    在Tomcat的catalina.sh文件中的启停server脚本中都应用到了两个变量: CATALINA_OPTS和JAVA_OPTS.用于保存Tomcat运行所需的各种参数. 他们在文件中的注释如 ...

  6. urlopen和urlretrieve

    import urllib import re url = "https://www.duitang.com/search/?kw=%E9%AC%BC%E6%80%AA&type=f ...

  7. 自学Java第五周的总结

    在这周里我在我要自学网上观看视频学习了有关java的基础知识,课程主要介绍JavaSE,这是整个Java体系的基础:课程将由浅入深,并结合案例进行讲解,在那里我将自己已学的知识进行了巩固,并由学习到了 ...

  8. Nginx配置服务器静态文件支持跨域访问

    在server中配置 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers X-Reque ...

  9. Java用Jackson遍历json所有节点

    <!-- jackson begin --> <dependency> <groupId>com.fasterxml.jackson.core</groupI ...

  10. django框架基础

    所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 最简单的web框架 import socket sk = socke ...