首页 > 代码库 > bzoj 2084

bzoj 2084

传送门: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;}

 

bzoj 2084