马拉车也是可以做的而且复杂度更优。我还是菜啊没有看出来单调性,这个取反翻转操作是单调的,你一个大的串如果是反对称串,中间的任何一个也肯定是啊因为翻转的位置并没有变...那么枚举起点,二分子串长度判断即可,然后比较坑的就是答案要用longlong存。复杂度。因为取反后翻转这个操作,所以不可能有奇数串符合条件(奇数串取反后翻转了一定不相等)

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N = 500010;
const ull base = 13131;

ull h1[N], h2[N], p[N];
int n;ll ans = 0;
char s[N];

ull get_h1(int l, int r) { return h1[r] - h1[l - 1] * p[r - l + 1]; }
ull get_h2(int l, int r) { return h2[l] - h2[r + 1] * p[r - l + 1]; }

int check(int x) {
    int l = 1, r = min(x, n - x);
    while(l <= r) {
        int mid = (l + r) >> 1;
        if(get_h1(x - mid + 1, x) == get_h2(x + 1, x + mid)) l = mid + 1;
        else r = mid - 1;
    }
    return r;
}

int main() {
    scanf("%d%s", &n, s + 1); p[0] = 1;
    for(int i = 1; i <= n; ++i) p[i] = p[i - 1] * base, h1[i] = h1[i - 1] * base + (ull)s[i];
    for(int i = n; i; --i) h2[i] = h2[i + 1] * base + (ull)(s[i] == '0' ? s[i] + 1 : s[i] - 1);
    for(int i = 1; i < n; ++i) ans += check(i);
    printf("%lld\n", ans);
}