先不考虑”不是连续的一段“这一个约束条件。可以知道:第$i$位与第$j$位相同,可以对第$\frac{i+j}{2}$位置上产生$1$的贡献(如果$i+j$为奇数表明它会对一条缝产生$1$的贡献),而每一个位置上或缝上的满足条件的字符串的个数就是$2^\text{贡献}-1$。把$\frac{1}{2}$忽略掉,也就是说:第$i$位与第$j$位相同时会在第$i+j$位产生$1$的贡献。这个是经典的生成函数+$FFT$求解的问题。具体来说,将$a,b$两个字母分开计算,以计算$a$的贡献为例,如果第$i$位上为$a$,则两个多项式的$x^i$项的系数为$1$,否则为$0$,然后将两个多项式做卷积得到的结果的每一项的系数就是$a$字母对每一位做的贡献,$b$同理。
然后我们考虑减掉连续的一段。连续的一段就是一段回文串,使用$Manacher$求解即可。
#include<bits/stdc++.h> #define ld long double //This code is written by Itst using namespace std; inline int read(){ ; ; char c = getchar(); while(c != EOF && !isdigit(c)){ if(c == '-') f = ; c = getchar(); } while(c != EOF && isdigit(c)){ a = (a << ) + (a << ) + (c ^ '); c = getchar(); } return f ? -a : a; } , MOD = 1e9 + ; ] , news[MAXN]; struct comp{ ld x , y; comp(ld _x = , ld _y = ){ x = _x; y = _y; } comp operator +(comp a){ return comp(x + a.x , y + a.y); } comp operator -(comp a){ return comp(x - a.x , y - a.y); } comp operator *(comp a){ return comp(x * a.x - y * a.y , x * a.y + y * a.x); } }A[MAXN]; int need , dir[MAXN] , calc[MAXN] , manacher[MAXN]; ); inline int poww(long long a , int b){ ; while(b){ ) times = times * a % MOD; a = a * a % MOD; b >>= ; } return times; } inline void swap(comp& a , comp& b){ comp t = a; a = b; b = t; } inline void FFT(int type){ comp wn , w; ; i < need ; ++i) if(i < dir[i]) swap(A[i] , A[dir[i]]); ; i < need ; i <<= ){ wn = comp(cos(pi / i) , type * sin(pi / i)); ; j < need ; j += i << ){ w = comp( , ); ; k < i ; ++k , w = w * wn){ comp x = A[j + k] , y = A[i + j + k] * w; A[j + k] = x + y; A[i + j + k] = x - y; } } } } int main(){ #ifndef ONLINE_JUDGE freopen("4199.in" , "r" , stdin); //freopen("4199.out" , "w" , stdout); #endif scanf("%s" , s); ; need = ; ) need <<= ; ; i < need ; ++i) dir[i] = (dir[i >> ] >> ) | (i & ? need >> : ); ; i < l ; ++i) if(s[i] == 'a') A[i].x = ; FFT(); ; i < need ; ++i) A[i] = A[i] * A[i]; FFT(-); ; i < need ; ++i) calc[i] = A[i].x / need / + 0.6; memset(&A , , sizeof(A)); ; i < l ; ++i) if(s[i] == 'b') A[i].x = ; FFT(); ; i < need ; ++i) A[i] = A[i] * A[i]; FFT(-); ; i < need ; ++i){ calc[i] += A[i].x / need / + 0.6; sum = (sum + poww( , calc[i]) - ) % MOD; } ; i < l ; ++i) news[(i << ) + ] = s[i]; , maxI = ; ; i < l << ; ++i){ if(maxD > i) manacher[i] = min(manacher[maxI * - i] , maxD - i - ); && i + manacher[i] <= l << && news[i - manacher[i]] == news[i + manacher[i]]) ++manacher[i]; sum = (sum - (manacher[i] >> ) + MOD) % MOD; if(i + manacher[i] > maxD){ maxD = i + manacher[i]; maxI = i; } } cout << sum; ; }