牛客p13506 H.Rock Paper Scissors FFT

题意:给两个字符串s,t,包括S,R,P,你可以调整t的位置,求t串最多能赢多少次,遵循剪刀石头布的原则。
题解:首先的想法是将赢变成有多少个字符串是相同的,变成了字符串相互匹配的问题。注意到只有三个元素不妨单独来算。那S来举例,将s,t中所有的S换成1,其他的换成0,将s,t看成是多项式 就是求 m a x ∑ s i + k ∗ t i max \sum s_{i+k}*t_{i} max∑si+k​∗ti​为。我们知道多项式乘法 C i = ∑ j = 0 i a j ∗ b i − j C_i=\sum_{j=0}^{i} a_j*b_{i-j} Ci​=∑j=0i​aj​∗bi−j​不妨将t翻转,就可以得到答案。多项式乘法用FFT 就行

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
const double pi=acos(-1);
struct cp{
	double r,i;
	cp(){}
	cp(double x,double y){
		r=x;i=y;
	}
	cp operator +(const cp &a) const {
		return cp(r+a.r,i+a.i);
	} 
	cp operator - (const cp &a) const{
		return cp(r-a.r,i-a.i);
	}
	cp operator * (const cp &a)const {
		return cp(r*a.r-i*a.i,r*a.i+i*a.r);
	}
}a[N<<2],b[N<<2];
int R[N<<2];//反码 
int n,m,len,L,Len;
int ans[N<<2];
char s[N<<2],t[N<<2];

inline void fft(cp *a,int len,int op){
	
	for(int i=0;i<len;i++) {
		if(i<R[i]) swap(a[ i ],a[ R[i] ]);
	}
	for(int i=2;i<=len;i<<=1){// 
		cp wn=cp(cos(2*pi/i), op*sin(2*pi/i));//单位复数根 
		for(int j=0;j<len;j+=i){
			cp w=cp(1.0,0.0);
			for(int k=j;k<j+(i/2);k++,w=w*wn){
				cp u=a[k];
				cp v=w*a[k+i/2]; 
				a[k]=u+v;
				a[k+i/2]=u-v;
			}
			
		}
		
		
	}
	if(op==-1) for(int i=0;i<len;i++) a[i].r/=len;
}
void calc(char op){
	memset(a,NULL,sizeof a);
	memset(b,NULL,sizeof b);
	for(int i=0;i<Len;i++) a[i].r=(s[i]==op?1:0);
	for(int i=0;i<Len;i++) b[i].r=(t[i]==op?1: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++) ans[i]+=(int)(a[i].r+0.5);
}


int main(){
	scanf("%d%d",&n,&m);
	scanf("%s",s);scanf("%s",t);
//	cout<<s<<" "<<t<<endl;	
	for(int i=0;i<n;i++){
		if(s[i]=='P') s[i]='S';
		else if(s[i]=='R') s[i]='P';
		else s[i]='R';
	}
//	cout<<t<<endl;
	reverse(t,t+m);
	len=n+m-1;L=0; 
	for(Len=1;Len<len;Len<<=1) L++;  
	for(int i=0;i<Len;i++) R[i]=(R[i>>1]>>1)|(i&1)<<(L-1);
//

	calc('P');calc('R');calc('S');
	int Ans=0;
	for(int i=m-1;i<len;i++) {
		Ans=max(Ans,ans[i]);
	}
	cout<<Ans<<endl;
	return 0;
}
/*
12 3  
RRRRRRRRRRRR
RSS

*/
上一篇:NC11166 H.Hash Function(fft)


下一篇:频谱细化-----Zoom-FFT算法介绍及MATLAB实现