P3546 PRE-Prefixuffix Sol
这题挺妙的。
有两个串 , 与 一定循环同构。
利用这个性质可以解决这道题目。
设 表示使得 成立的最大 。
因为原串的 border 很好找,所以寻找中间 的关系。
考虑如何转移,观察 与 。
考虑一个字符 ,有 与 循环同构, 对应 。
此时除去首、尾的串 仅剩 。
那么原来的 border 为 ,现在的 border 为 。
这是最劣情况,也就是说,。
那么就维护一个指针实时统计答案即可。
指针移动次数至多为 ,复杂度正确。
最后再判一下 是否合法即可计算答案。
注意哈希卡自然溢出。
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const int N = 1e6 + 10;
const ll bas = 131, Mod = 998244353; int n, dp[N];
ll hsh[N], pw[N]; char str[N];
inline ll qry(int l, int r) {
return (hsh[r] - hsh[l - 1] * pw[r - l + 1] % Mod + Mod) % Mod;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0), cout.tie(0);
cin >> n; for (int i = 1; i <= n; ++i) cin >> str[i];
pw[0] = 1; for (int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * bas % Mod;
for (int i = 1; i <= n; ++i) hsh[i] = (hsh[i - 1] * bas + str[i]) % Mod;
for (int len = n / 2; len; --len) {
dp[len] = dp[len + 1] + 2;
while (dp[len] + len > n / 2) --dp[len];
while (dp[len] && qry(len + 1, len + dp[len]) != qry(n - len - dp[len] + 1, n - len)) --dp[len];
}
int res = 0;
for (int i = 1; i <= n / 2; ++i)
if (qry(1, i) == qry(n - i + 1, n)) res = max(res, i + dp[i]);
cout << res << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现