P5446
-
由翻转可知:
-
因此 R 是 S 的前缀 且 R 的后缀是回文串
- 用 Manacher 算出最大回文半径 d
-
此外,R 也可以由多次反转得到
- 条件是:
- R' 经过反转后是符合
R 是 S 的前缀 且 R 的后缀是回文串
的 - 且 R' 本身是回文串,这使得 R' 翻转后得到 R
- R' 经过反转后是符合
# include <bits/stdc++.h> # define int long long using namespace std; const int N = (int)1e6 + 10; int t; int l, r, d[N]; bool vis[N]; char s[N]; void Manacher(int n){ int l = 0, r = 0; s[0] = '@', s[n + 1] = '#'; for(int i = 1; i <= n; i++){ d[i] = 0; if(i > r){ while(s[i + d[i]] == s[i - d[i]]){ d[i]++; } l = i - d[i] + 1; r = i + d[i] - 1; }else{ int j = l + (r - i); if(j - d[j] >= l){ d[i] = d[j]; }else{ d[i] = r - i; while(s[i + d[i]] == s[i - d[i]]){ d[i]++; } l = i - d[i] + 1; r = i + d[i] - 1; } } } for(int i = 1; i <= n; i++){ d[i]--; } } signed main(){ // freopen("1.in", "r", stdin); cin >> t; while(t--){ cin >> (s + 1); int n = strlen(s + 1); Manacher(n); for(int i = n; i >= 1; i--){ if(i + d[i] == n){ vis[i] = 1; }else if(vis[i + d[i]] == 1 && i - d[i] == 1){ vis[i] = 1; } } for(int i = 1; i <= n; i++){ if(vis[i] == 1){ cout << i << " "; } vis[i] = 0; } cout << "\n"; } } - 条件是:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话