[HYSBZ 3160] 万径人踪灭 (FFT + Manacher)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ike940067893/article/details/85240342

AC code

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXM = 1<<18;
const int mod = 1e9 + 7;
#define LL long long
char s[MAXN], str[MAXN<<1];
int n;

int init()
{
	int len = 0;
	str[len] = '@'; //Head
	for(int i = 1; i <= n; ++i)
		str[++len] = '#', str[++len] = s[i];
	str[++len] = '#';
	str[len+1] = '$'; //Tail
	return len;
}
int ext[MAXN<<1];
int Manacher(int len)
{
	int Mid = 0, R = 0, ret = 0;
	for(int i = 1; i <= len; ++i)
	{
		ext[i] = i < R ? min(R - i, ext[Mid*2 - i]) : 1;
		while(str[i-ext[i]] == str[i+ext[i]]) ++ext[i];
		if(i + ext[i] > R) R = i + ext[i], Mid = i;
		ret = (ret + ext[i]/2) % mod;
	}
	return ret;
}

const double Pi = acos(-1.0);
struct complex
{
    double r, i;
    complex(double _r=0, double _i=0):r(_r), i(_i){}
    complex operator +(const complex &t)const
    {
        return complex(r + t.r, i + t.i);
    }
    complex operator -(const complex &t)const
    {
        return complex(r - t.r, i - t.i);
    } 
    complex operator *(const complex &t)const
    {
        return complex(r * t.r - i * t.i, r * t.i + i * t.r);
    }
}f[MAXM], g[MAXM];
inline void change(complex arr[], const int &len)
{
    for(int i = 1, j = len/2; i < len-1; ++i)
    {
        if(i < j) swap(arr[i], arr[j]);
        int k = len/2;
        while(j >= k) j -= k, k >>= 1;
        j += k;
    }
}
inline void fft(complex arr[], const int &len, const int &flg)
{
    change(arr, len);
    for(int i = 2; i <= len; i<<=1)
    {
        complex wn = complex(cos(2*Pi/i), sin(2*Pi/i) * flg);
        for(int j = 0; j < len; j += i)
        {
            complex w = complex(1, 0);
            for(int k = j; k < j + i/2; ++k)
            {
                complex A0 = arr[k], wA1 = w * arr[k + i/2];
                arr[k] = A0 + wA1;
                arr[k + i/2] = A0 - wA1;
                w = w * wn;
            }
        }
    }
    if(flg == -1) for(int i = 0; i < len; ++i) arr[i].r /= len;
}
int solve() { return Manacher(init()); }
int ans[MAXM];

inline int qmul(int a, int b)
{
	int ret = 1;
	while(b)
	{
		if(b&1) ret = (LL)ret * a % mod;
		a = (LL)a * a % mod; b >>= 1;
	}
	return ret;
}

int calc()
{
	int len = 1; while(len <= n<<1) len<<=1;
	for(int i = 1; i <= n; ++i) if(s[i] == 'a') f[i] = complex(1, 0);
	for(int i = 1; i <= n; ++i) if(s[i] == 'b') g[i] = complex(1, 0);
	fft(f, len, 1), fft(g, len, 1);
	for(int i = 0; i < len; ++i) f[i] = f[i] * f[i] + g[i] * g[i];
	fft(f, len, -1);
	int ret = 0;
	for(int i = 2; i <= n<<1; ++i)
		ret = (ret + qmul(2, (int(f[i].r + 0.5) + 1) >> 1) - 1) % mod;
	return ret;
}

int main ()
{
	scanf("%s", s+1), n = strlen(s+1);
	int Ans = (mod - solve()) % mod;
	printf("%d\n", (Ans + calc()) % mod);
}

猜你喜欢

转载自blog.csdn.net/Ike940067893/article/details/85240342