FFT模板(以Rock Paper Scissors为例)

https://cn.vjudge.net/problem/Gym-101667H

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+5;
const double PI = acos(-1.0);
struct cp
{
	double a,b;
	cp(double x=0.0,double y=0.0):a(x),b(y){};
	cp operator +(cp temp)
	{
		return cp(temp.a+a,temp.b+b);
	}
	cp operator -(cp temp)
	{
		return cp(a-temp.a,b-temp.b);
	}
	cp operator *(cp temp)
	{
		return cp(temp.a*a-temp.b*b,temp.b*a+temp.a*b); 
	}
 };
int rev[maxn];
void getrev(int bit)
{
	for(int i=0;i<(1<<bit);i++)
	{
		rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
	}
}
void fft(cp a[],int n,int dft)
{
	for(int i=0;i<n;i++)
	{
		if(i<rev[i]) swap(a[i],a[rev[i]]); 
	}
	for(int step=1;step<n;step<<=1)
	{
		cp wn (cos(dft*2*PI/(step*2)),sin(dft*2*PI/(step*2)));
		for(int j=0;j<n;j+=step<<1)
		{
			cp wnk(1.0,0.0);
			for(int k=j;k<j+step;k++)
			{
				cp x = a[k];
				cp y = wnk*a[k+step];
				a[k] = x+y;
				a[k+step] = x-y;
				wnk = wnk *wn;
			 } 
		}
	}
	if(dft==-1)
	{
		for(int i=0;i<n;i++)
		{
			a[i].a/=n;
		}
	}
	return ;
}
string S,T;
cp s[maxn],t[maxn];
void change(char a,int n,int m)
{
	for(int i=0;i<n;i++)
	{
		s[i].a = (S[i]==a?1.0:0.0);
	}
	for(int i=0;i<m;i++)
	{
		t[i].a = (T[i]==a?1.0:0.0);
	}
}
int ans[maxn];
int n,m;
void print1()
{
	for(int i=0;i<n;i++)
	{
		cout<<s[i].a<<" "; 
	}cout<<endl;	
}
void print2()
{
	for(int i=0;i<m;i++)
	{
		cout<<t[i].a<<" "; 
	}cout<<endl;	
}
void solve(char a,int len,int n,int m)
{
	for(int i=0;i<len;i++)
	{
		s[i] = cp(0,0); 
		t[i] = cp(0,0); 
	}
	change(a,n,m);
//	print1();
	fft(s,len,1);
//	print1();
	fft(t,len,1);
	for(int i=0;i<len;i++)
		s[i]=s[i]*t[i];
	fft(s,len,-1);
	for(int i=m-1;i<len;i++)
	{
		ans[i]+=int(s[i].a+0.5);
	 } 
}
int main()
{
	int i,j,k;
	cin>>n>>m>>S>>T;
	for(i=0;i<m/2;i++)
	{
		swap(T[i],T[m-1-i]);
	}
	char sss[100];
	sss['R'-'A']='S';
	sss['S'-'A']='P';
	sss['P'-'A']='R';
	for(i=0;i<m;i++) T[i]=sss[T[i]-'A'];
//	cout<<"----------------"<<T<<endl;
	int len=2;
	for(i=1;(1<<i)<(n+m-1);i++)len<<=1;
	getrev(i);
	solve('P',len,n,m); 
	solve('S',len,n,m); 
	solve('R',len,n,m); 
	int _max=-1;
	for(i=0;i<n+m+1;i++) _max=max(_max,ans[i]);
	cout<<_max<<endl;
}

NTT模板

const int mod=998244353;
const int g=3;
int fac[maxn],inv[maxn];
int rev[maxn];
void getRev(int bit){
	for(int i=0;i<(1<<bit);i++){
		rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
	}
}
void NTT(int a[],int n,int o){
	for(int i=0;i<n;i++){
		if(i<rev[i]) swap(a[i],a[rev[i]]);
	}
	for(int step=1;step<n;step<<=1){
		int Wn=qpow((o==1?g:qpow(g,mod-2)),(mod-1)/(step<<1));
		for(int i=0;i<n;i+=(step<<1)){
			int w=1;
			for(int k=i;k<i+step;k++){
				int x=a[k];
				int y=1ll*w*a[k+step]%mod;
				a[k]=((x+y)%mod+mod)%mod;
				a[k+step]=((x-y)%mod+mod)%mod;
				w=1ll*w*Wn%mod;
			}
		}
	}
	if(o==-1){
		long long iv=qpow(n,mod-2);
		for(int i=0;i<n;i++)a[i]=1ll*a[i]*iv%mod;
	}
}

FWT模板

or

//Log为位数
void FWT(ll *a,int opt) {
	for (int bit = 1; bit <= Log; bit++)
	for (int i = 0; i < n; i += 1 << bit)
	for (int j = i, k = i + (1 << (bit - 1)); k < i + (1 << bit); j++, k++)
	{
		a[k] += opt*a[j];
		if (a[k] >= P) a[k] -= P;
		if(a[k]<0) a[k]+=P;
	}
}

Q.E.D.