题解:
因为和回文串定义类似,且数据范围很大,那么就可以想到是Manacher了。
把增加回文半径那里的判断条件改改就可以了。
复杂度:
时间复杂度O(n),空间复杂度O(n)。
WA:
因为答案只可能是偶数串,更新mx那里还得判断,WA了3发。
GET:
自己想到了用Manacher,也注意到答案只可能是偶数串。
但是写挂了2333,没有深刻理解Manacher吧。
/* Telekinetic Forest Guard */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 500005;
int n, len, p[maxn << 1];
char str[maxn], s[maxn << 1];
inline bool check(int i) {
if(s[i + p[i]] != s[i - p[i]]) return (s[i + p[i]] - '0') + (s[i - p[i]] - '0') == 1;
return s[i + p[i]] == '#';
}
int main() {
scanf("%d%s", &n, str); len = (n << 1) + 2;
s[0] = '&';
for(int i = 0; i <= n; i++) {
s[(i << 1) + 1] = '#';
s[(i << 1) + 2] = str[i];
}
LL ans = 0;
int id = 0, mx = 0;
for(int i = 1; i < len; i++) {
p[i] = mx > i ? min(p[(id << 1) - i], mx - i) : 1;
for(; check(i); p[i]++);
if(p[i] + i > mx && (i & 1)) {
mx = p[i] + i;
id = i;
}
if(i & 1) ans += (p[i] - 1) >> 1;
}
printf("%lld\n", ans);
return 0;
}