传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2084
这道题很容易想到就是一个变种的最长回文字串, 不过回文的规则变成了s[i + p[i]] + s[i - p[i]] == 1 可以用hash 来nlogn, 不过最优是用manacher, 然后有一个非常迷的查空位的方法(' ' ) 可以看代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 20000100;
int n; long long ans = 0;
char s[maxn];
int st[maxn];
void read() {
scanf("%d", &n);
scanf("%s", s + 1);
for(int i = 1; i <= n; ++ i) st[i << 1] = (s[i] == '0' ? 0 : 2);
n <<= 1; ++ n;
for(int i = 1; i <= n; i += 2) st[i] = 1;
}
int p[maxn];
void sov() {
int mx, id; mx = 0, id = 0;
for(int i = 1; i <= n; i += 2) {
if(mx > i) p[i] = min(p[2 * id - i], mx - i);
else p[i] = 1;
for(; i - p[i] > 0 && i + p[i] <= n && st[i - p[i]] + st[i + p[i]] == 2; ++ p[i]);
if(i + p[i] > mx) mx = i + p[i], id = i;
}
for(int i = 1; i <= n; i += 2) ans += (long long)((p[i] - 1) >> 1);
printf("%lld\n", ans);
}
int main() {
//freopen("test.in", "r", stdin);
read(), sov();
return 0;
}