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;
}
京公网安备 11010502036488号