第一次见到这种题,没想到fft还能这么用,补体的时候换了好多个版本,wa了差不多一整页才过,有点难受。
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn = 1e6 + 7;
const double pi = acos(-1.0);
int sum[maxn];
int res[maxn];
int rev[maxn];
struct cp
{
double r, i;
cp(double _r = 0.0, double _i = 0.0)
{
r = _r;
i = _i;
}
cp operator +(const cp &p) const
{
cp xx;
xx.i=i + p.i;
xx.r=r + p.r;
return xx;
}
cp operator -(const cp &p)const
{
cp xx;
xx.i=i - p.i;
xx.r=r - p.r;
return xx;
}
cp operator *(const cp &p) const
{
cp xx;
xx.r = r * p.r + - i * p.i;
xx.i = r * p.i + i * p.r;
return xx;
}
};
void change(cp y[], int len)
{
for(int i = 1, j = len / 2; i < len - 1; i++)
{
if(i < j) swap(y[i], y[j]);
int k = len / 2;
while(j >= k)
{
j -= k;
k >>= 1;
}
if(j < k)
j += k;
}
}
void fft(cp y[], int len, int op)
{
change(y, len);
for(int h = 2; h <= len; h<<=1)
{
cp wn(cos(-op * 2 * pi / h), sin(-op* 2 * pi / h));
for(int j = 0; j < len; j += h)
{
cp w(1, 0);
for(int k = j; k < j + h / 2; k++)
{
cp u = y[k];
cp t = w * y[k + h / 2];
//printf("%f %f %f %f %f %f\n", y[k].r, y[k].h, w.r, w.i, t.r, t.i);
y[k] = u + t;
y[k + h/ 2] = u - t;
w = w * wn;
}
}
}
if(op == -1)
for(int i = 0; i < len; i++)
y[i].r /= len;
}
cp a[maxn], b[maxn];
char s[maxn], p[maxn];
void conv(char w, int n,int m)
{
int len = 1;
while(len < n * 2 || len < m * 2) len<<=1;
for(int i = 0; i < n; i++)
{
if(s[i] == w) a[i] = cp(1, 0);
else a[i] = cp(0, 0);
}
for(int i = n; i < len; i++)
{
a[i] = cp(0, 0);
}
for(int i = 0; i < m; i++)
{
if(p[i] == w) b[i] = cp(1, 0);
else b[i] = cp(0, 0);
}
for(int i = m; i < len; i++)
b[i] = cp(0, 0);
fft(a, len, 1);
fft(b, len, 1);
for(int i = 0; i < len; i++)
a[i] = a[i] * b[i];
fft(a, len, -1);
for(int i = 0; i < len; i++)
sum[i] += (int)(a[i].r + 0.5);
}
int main()
{
int len1, len2;
scanf("%d%d", &len1, &len2);
scanf("%s%s", s, p);
for(int i = 0; i < len2; i++)
{
if(p[i] == 'S') p[i] = 'P';
else if(p[i] == 'P') p[i] = 'R';
else if(p[i] == 'R') p[i] = 'S';
}
reverse(p, p + len2);
conv('S' ,len1, len2);
conv('R', len1, len2);
conv('P', len1, len2);
int ans = -0x3f3f3f3f;
for(int i = len2 - 1; i < len1 + len2 - 1; i++)
ans = max(ans, sum[i]);
printf("%d\n", ans);
return 0;
}