P4287 [SHOI2011]双倍回文 解题报告
Desciption
给定一个字符串 , 求 的最长双倍回文子串。
双倍回文串定义为长度为4的倍数,并且满足 形式的字符串。
为字符串 的倒置。长度为偶数的普通回文串的形式为 。
Solution
~~貌似是 PAM 的基础题,不过我暂时不会。~~
看到回文串考虑 manachar。我们发现在 manachar 的实现过程中实际上证明了一个性质,就是一个串的本质不同的回文子串的个数是 的。而产生一个新的本质不同回文子串只有可能在更新 mx 的时候出现,这个时候直接暴力对每个新产生的回文子串判断一下即可。于是做完啦。
Code

#include<bits/stdc++.h> using namespace std; inline int read() { int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -f; c = getchar();} while (c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();} return x * f; } const int N = 5e5 + 10; int n, p[N<<1]; char s[N], str[N<<1]; inline void manachar() { int len = 1, ans = 0; str[0] = '$'; str[1] = '#'; for (int i = 1; i <= n; ++ i) str[++len] = s[i], str[++len] = '#'; for (int i = 1, mx = 0, id = 0; i <= len; ++ i) { if (i < mx) p[i] = min(p[2*id-i], mx - i); else p[i] = 1; while (str[i+p[i]] == str[i-p[i]]) ++p[i]; if (i + p[i] > mx) { if (i & 1) for (int j = max(mx, i + 4); j < i + p[i]; ++ j) if (!(j-i & 3) && p[i-(j-i)/2] > (j-i)/2) ans = max(ans, j - i); mx = i + p[i], id = i; } } printf("%d\n", ans); } int main () { n = read(); scanf("%s", s + 1); manachar(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!