FFT字符串区间匹配最大值

Posted 爷灬傲奈我何123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FFT字符串区间匹配最大值相关的知识,希望对你有一定的参考价值。

FFT能处理模式串和匹配串的最大匹配问题。
通常是把模式串翻转,然后分字母对答案的贡献,最后取个最大值就可以了。
链接
题意
给你两个串,长度分别为n,m。每个串由三个字符组成’R’,‘P’,‘S’,分别代表着石头剪刀布,第一个串代表是机器出的,第二个串代表是你出的,现在,你已知了机器出的顺序,可以跳过任意个,但是一旦开始就必须进行到比赛结束,所以,问最多赢几盘?

数据范围: 1 < m < n < 1 e 5 1<m<n<1e51<m<n<1e5
代码:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1000010;
const double PI=acos(-1);
struct Complex{
	double x;
	double y;
	Complex operator*(const Complex&tt)const
	{
		return {x*tt.x-y*tt.y,x*tt.y+y*tt.x};
	}
	Complex operator-(const Complex&tt)const{
		return {x-tt.x,y-tt.y};
	}
	Complex operator+(const Complex&tt)const
	{
		return {x+tt.x,y+tt.y};
	}
}a[N],b[N];
int tot;
int bit;
int rev[N];
void fft(Complex a[],int inv)
{
	for(int i=0;i<tot;i++)	if(i<rev[i])		swap(a[i],a[rev[i]]);
	for(int mid=1;mid<tot;mid*=2)
	{
		Complex w={cos(PI/mid),inv*sin(PI/mid)};
		for(int i=0;i<tot;i+=2*mid)
		{
			Complex wk={1,0};
			for(int j=0;j<mid;j++,wk=wk*w)
			{
				auto x=a[i+j];
				auto y=wk*a[i+j+mid];
				a[i+j]=x+y;
				a[i+j+mid]=x-y;
			}
		}
	}

	if(inv==-1)
		for(int i=0;i<tot;i++)
			a[i].x/=tot;
}
string s,t;
int ans[N];
int n,m;
void solve(char x,char y)
{
	for(int i=0;i<tot;i++)
	{
		a[i].x=0;
		b[i].x=0;
		b[i].y=0;
		a[i].y=0;
	}
	for(int i=0;i<s.size();i++)
		if(s[i]==y)
			a[i].x=1;
	for(int i=0;i<t.size();i++)
		if(t[i]==x)
			b[i].x=1;
	fft(a,1),fft(b,1);
	for(int i=0;i<tot;i++)
		a[i]=a[i]*b[i];
	fft(a,-1);
	for(int i=m-1;i<tot;i++)
		ans[i]+=int(a[i].x+0.5);
}
int main()
{
	
	cin >> n >> m ;
	
	cin>>s;
	cin>>t;
	reverse(t.begin(),t.end());
	while((1<<bit)<n+m)	bit++;
	tot=(1<<bit);
	for(int i=0;i<tot;i++)
		rev[i]=((rev[i>>1]>>1) | (i&1)<<(bit-1));
	solve('R','S');
	solve('S','P');
	solve('P','R');
	int maxv=0;
	for(int i=m-1;i<tot;i++)
			maxv=max(maxv,ans[i]);
	cout<<maxv<<endl;
	return 0;
}

以上是关于FFT字符串区间匹配最大值的主要内容,如果未能解决你的问题,请参考以下文章

FFT与图像最大互相关算法

FFT字符串匹配

FFT字符串匹配

2021-12-24:划分字母区间。 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 力扣763。某大厂面试

Hdu 2236 无题II 最大匹配+二分

P4173 残缺的字符串 fft