题意:
给一个s串 一个t串,串中只有三种字母 分别代表剪刀石头布,问t串和s串中那个匹配使t串赢得最多。
fft加速卷积解模式串匹配的入门题。
考虑t出剪刀 s出布的情况:
将t中剪刀全部置1,s中布全部置1 其他置0。然后将t倒置,FFT(s,t)后得出的 x^i的系数 = (t1si-1 +t2si-2 ……) 即与某一位对齐时的 出剪刀的赢得场次
其余情况同理。
三次FFT 最后相加找出最大的系数即可。
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
#define for1(I, A, B) for (int I = (A); I < (B); ++I)
#define forn(I, A, B) for (int I = (A); I <= (B); ++I)
#define Mod(a,b) a<b?a:a%b+b
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define show(x) cout<<#x<<"="<<x<<endl
#define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show5(v,w,x,y,z) cout<<#v<<"="<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showmm(x,a,b) rep(i,0,a) rep(j,0,b) cout<<#x<<'['<<i<<']'<<'['<<j<<"]="<<x[i][j]<<(" \n"[j==b])
#define showm(x,a,b) rep(i,0,a) rep(j,0,b) cout<<x[i][j]<<(" \n"[j==b])
#define showa1(x,a,b) cout<<#x<<":\n";rep(i,a,b) showa(x,i);cout<<endl
#define showa2(x,a,b) cout<<#x<<": ";rep(i,a,b) cout<<x[i]<<' ';cout<<endl
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef set<int> si;
typedef double db;
const db eps=1e-8;
const db Pi=acos(-1);
const ll inf=0x3f3f3f3f3f3f3f3f;
const int INF=0x3f3f3f3f;
const int MAX=1e6+10;
const ll mod=1e9+7;
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
const int MAXN=1e6+10;
struct cp
{
double x,y;
cp (double xx=0,double yy=0)
{
x=xx,y=yy;
}
} a[MAXN],b[MAXN];
cp operator + (cp a,cp b)
{
return cp(a.x+b.x, a.y+b.y);
}
cp operator - (cp a,cp b)
{
return cp(a.x-b.x, a.y-b.y);
}
cp operator * (cp a,cp b)
{
return cp(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x);
}
int N,M;
int l,r[MAXN];
int limit=1;
void fast_fast_tle(cp *A,int type)
{
for(int i=0; i<limit; i++)
if(i<r[i]) swap(A[i],A[r[i]]);//@求出要迭代的序列@
for(int mid=1; mid<limit; mid<<=1) //@待合并区间的中点@
{
cp Wn( cos(Pi/mid), type*sin(Pi/mid) ); //@单位根@
for(int R=mid<<1,j=0; j<limit; j+=R) //@R是区间的右端点,j表示前已经到哪个位置了@
{
cp w(1,0);//@幂@
for(int k=0; k<mid; k++,w=w*Wn) //@枚举左半部分@
{
cp x=A[j+k],y=w*A[j+mid+k];//@蝴蝶@
A[j+k]=x+y;
A[j+mid+k]=x-y;
}
}
}
}
ll ans[MAX];
int main()
{
IO;
cin>>N>>M;
while(limit<=N+M) limit<<=1,l++;
for(int i=0; i<limit; i++)
r[i]= ( r[i>>1]>>1 )| ( (i&1)<<(l-1) ) ;
string s1,s2;
cin>>s1>>s2;
reverse(s2.begin(),s2.end());
for1(i,0,N)if(s1[i]=='R')a[i].x = 1;
for1(i,0,M)if(s2[i]=='P')b[i].x = 1;
fast_fast_tle(a,1);
fast_fast_tle(b,1);
for(int i=0; i<=limit; i++) a[i]=a[i]*b[i];
fast_fast_tle(a,-1);
for(int i=0; i<=N; i++)
{
ans[i]+=(ll)(a[i+M-1].x/limit+0.5);
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for1(i,0,N)if(s1[i]=='S')a[i].x = 1;
for1(i,0,M)if(s2[i]=='R')b[i].x = 1;
fast_fast_tle(a,1);
fast_fast_tle(b,1);
for(int i=0; i<=limit; i++) a[i]=a[i]*b[i];
fast_fast_tle(a,-1);
for(int i=0; i<=N; i++)
{
ans[i]+=(ll)(a[i+M-1].x/limit+0.5);
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for1(i,0,N)if(s1[i]=='P')a[i].x = 1;
for1(i,0,M)if(s2[i]=='S')b[i].x = 1;
fast_fast_tle(a,1);
fast_fast_tle(b,1);
for(int i=0; i<=limit; i++) a[i]=a[i]*b[i];
fast_fast_tle(a,-1);
for(int i=0; i<=N; i++)
{
ans[i]+=(ll)(a[i+M-1].x/limit+0.5);
}
ll ANS=0;
for(int i=0;i<=N;i++)
{
ANS=max(ANS,ans[i]);
}
cout<<ANS<<endl;
return 0;
}