P3805 manacher算法
题目地址:https://www.luogu.com.cn/problem/P3805
思路
马拉车其实就是每次算某个点的回文半径到时候,会看自身是否处在一个之前求过的回文串T中,然后根据镜面对称,O(1)获取以自己为中心在T中的最大回文子串,然后再尝试暴力,所有的更新暴力复杂度为O(n)
代码
#include<bits/stdc++.h> #define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define debug freopen("in.txt","r",stdin),freopen("out.txt","w",stdout); #define PI acos(-1) #define fs first #define sc second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 2e7+2e6 + 10;//没错这题有512MB内存,这里最多会用到300MB using namespace std; string s; int ans[maxn],str[maxn],lef[maxn]; int build(const string &s){ int n = s.length(), m = (n + 1)*2, ret = 0; str[0] = '$'; str[m] = '@'; str[1] = '#'; ans[1] = 1; for (int i = 1; i <= n; i++) str[i*2] = s[i - 1], str[i*2+1] = '#'; ans[1] = 1; for (int r = 0, p = 0, i = 2; i < m; ++i){ if (r > i) ans[i] = min(r - i, ans[p * 2 - i]); else ans[i] = 1; while(str[i - ans[i]] == str[i + ans[i]]) ++ans[i]; if (i + ans[i] > r) r = i + ans[i], p = i; ret = max(ret, ans[i] - 1); } return ret; } int main(){ ios; cin>>s; int res = build(s); cout<<res<<endl; return 0; }