正题
金牌导航 Manacher-4
题目大意
给出一个字符串,让你用最少的回文串连接得到该串(这里连接是可以有重合的)
解题思路
先用Manacher求出以x为左端点的回文串右端点最大的位置
然后在当前回文串中贪心求下一回文串的右端点
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 50010
using namespace std;
int n, now, ans, last, s[N<<1], l[N<<1], r[N<<1];
string str;
void Manacher()
{int mid = 0, mx = 0;for (int i = 1; i <= n; ++i){if (i < mx) l[i] = min(l[mid * 2 - i], mx - i);else l[i] = 1;while(s[i + l[i]] == s[i - l[i]]) l[i]++;if (i + l[i] > mx){mx = i + l[i];mid = i;}r[i - l[i] + 1] = i + l[i] - 1;}
}
int main()
{while(cin>>str){memset(r, 0, sizeof(r));n = str.size();s[0] = s[1] = '#';for (int i = 1; i <= n; ++i){s[i * 2] = str[i - 1];s[i * 2 + 1] = '#';}n = n * 2 + 2;s[n] = 0;Manacher();now = last = r[1] + 2;//初始的回文串ans = 0;for (int i = 2; i <= n; ++i){if (i == last)last = now, ans++;//下一个回文串now = max(now, r[i] + 2);//贪心求最右的点}printf("%d\n", ans);}return 0;
}