[BZOJ2084][Poi2010]Antisymmetry

[BZOJ2084][Poi2010]Antisymmetry

输入示例

8
11001011


输出示例

7


题解

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i++)
#define dwn(i, s, t) for(int i = (s); i >= (t); i--)

int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}

#define maxn 500010

int n, alp[maxn<<1], len[maxn<<1];
char str[maxn], S[maxn<<1];

int main() {
scanf("%s", str + 1);

rep(i, 1, n) S[(i<<1)-1] = str[i] - '0' ^ (i & 1), S[i<<1] = '#';
n <<= 1;
rep(i, 1, n) alp[i] = alp[i-1] + (0 <= S[i] && S[i] <= 1);
len[1] = 1;
int mxi = 1;
rep(i, 2, n) {
len[i] = 1;
if(mxi + len[mxi] - 1 >= i) len[i] = min(max(1, len[(mxi<<1)-i]), mxi + len[mxi] - i);
while(i - len[i] > 0 && i + len[i] <= n && S[i-len[i]] == S[i+len[i]]) len[i]++;
if(mxi + len[mxi] < i + len[i]) mxi = i;
}

int ans = 0;
rep(i, 1, n) if(S[i] == '#')
ans += alp[i] - alp[i-len[i]];
printf("%d\n", ans);

return 0;
}

posted @ 2017-10-24 20:13  xjr01  阅读(142)  评论(0编辑  收藏  举报