标签:
做学长出的题目好开心:-)
提示:
1. 可以尝试去推导答案的公式 , 然后优化处理
详细题解代码后:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <cassert>
using namespace std;
struct complex
{
double x , y;
complex(double x=0 , double y=0):x(x),y(y){}
double real() { return x; }
double imag() { return y; }
complex operator +(complex b) { return complex(x + b.x , y + b.y); }
complex operator -(complex b) { return complex(x - b.x , y - b.y); }
complex operator *(complex b) { return complex(x * b.x - y * b.y , x * b.y + y * b.x);; }
complex operator /(double b) { return complex(x / b , y / b); }
};
typedef complex cd;
typedef vector<cd> vc;
typedef vector<double> vd;
void FFT(vc &a , int inv)
{
int n = a.size();
for(int i=0,j=0;i<n;i++)
{
if(j > i) swap(a[i] , a[j]);
int k = n;
while(j & (k >>= 1)) j &= ~k;
j |= k;
}
double Pi = inv * acos(-1);
for(int i=1;i<n;i <<= 1)
{
cd wn = cd(cos(Pi/i) , sin(Pi/i));
for(int j=0;j<n;j += i<<1)
{
cd w = cd(1 , 0);
for(int k=j;k<i+j;k++)
{
cd x = a[k];
cd y = a[k+i] * w;
a[k] = x + y;
a[k+i]=x - y;
w = w*wn;
}
}
}
if(inv == -1) for(int i=0;i<n;i++) a[i] = a[i] / n;
}
vd operator *(vd a , vd b)
{
int s1 = a.size() , s2 = b.size() , s = 2;
while(s <= s1 + s2) s <<= 1;
vc c(s , 0) , d(s , 0);
for(int i=0;i<s1;i++) c[i] = a[i];
FFT(c , 1);
for(int i=0;i<s2;i++) d[i] = b[i];
FFT(d , 1);
for(int i=0;i<s;i++) c[i] = c[i] * d[i];
FFT(c ,-1);
vd res(s1+s2-1 , 0);
for(int i=0;i<s1+s2-1;i++) res[i] = c[i].real();
return res;
}
const int maxn = 1e5+1e2;
const int modu = 1e9+7;
int n;
char s[maxn] , s1[maxn*2]; int p[maxn*2];
int manacher()
{
int res = 0 , cnt = 0;
s1[cnt++] = ‘c‘; s1[cnt++] = ‘d‘;
for(int i=0;i<n;i++) s1[cnt++] = s[i] , s1[cnt++] = ‘d‘;
int mx = 0 , id = 0;
for(int i=1;i<cnt;i++)
{
p[i] = mx > i ? min(mx - i, p[2*id - i]) : 1;
while(s1[i + p[i]] == s1[i - p[i]]) p[i]++;
(res += p[i]/2) %= modu;
if(i + p[i] > mx) mx = i + p[id = i];
}
return res;
}
int bits[maxn]={1};
int main(int argc, char *argv[]) {
scanf("%s" , s);
n = strlen(s);
vd a(n , 0) , b(n , 0);
for(int i=1;i<=n;i++) bits[i] = (bits[i-1]<<1) % modu;
for(int i=0;i<n;i++) if(s[i] == ‘a‘) a[i] = 1; else b[i] = 1;
a = a*a;
b = b*b;
int res = 0;
for(int i=0;i<a.size();i++) (res += bits[(int(a[i]+0.5) + int(b[i]+0.5) + 1)/2]-1) %= modu;
cout<< (res + modu - manacher())%modu <<endl;
return 0;
}
下述中
令
其中回文串的数量不难用
观察
令
标签:
原文地址:http://blog.csdn.net/fuxey/article/details/51367184