2017ACM ICPC Asia Regional-Daejeon H-Rock Paper Scissors[ FFT]

news/2024/7/6 1:05:11 标签: fft

题目大意

给你两个字符串,N,M |N|>|M|,经过转换之后,问你,连续的一段,能够匹配上的最大元素个数。
n <1e5

题目分析

题目求区间内匹配数最大。考虑区间有n^2个,暴力做显然会T,所以这里考虑,用FFT
将第二个串反置,这样我们相邻位置的匹配,可以转化为,对应位置的匹配

如下图:

在这里插入图片描述
此时我们发现,最大匹配数 就是 i+j的系数

因此,我们分别求R,S,P的匹配,三次FFT之后将系数加起来,求一个最大值即可

代码分析

#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e6+50;
const double pi = acos(-1.0);
typedef long long ll;
struct Complex
{
	double x,y;
	Complex(double _x = 0,double _y=0)
	{
		x=_x; y=_y;
	}
	Complex operator +(const Complex &b) const
	{
		return Complex(x+b.x,y+b.y);
	}
	Complex operator -(const Complex &b) const
	{
		return Complex(x-b.x,y-b.y);
	}
	Complex operator * (const  Complex&b) const
	{
		return Complex(x*b.x-y*b.y,x*b.y+y*b.x);
	}
}a[maxn],b[maxn];
int S,T,n,m,L,R[maxn],ans[maxn]; //S 表示A序列的长度 ,T表示B序列的长度
//n 表示 >=S+T 的2的幂次 L表示幂次 R数组是旋转数组,ans答案数组
ll F[maxn];
double f[maxn][3],g[maxn][3];// f,g数组是整数转化为实数的数组 
char x[maxn],y[maxn];
void FFT(Complex a[],int opt)
{
	for(int i=0;i<n;i++) if(i<R[i]) swap(a[i],a[R[i]]);// 翻转数组
	for(int k=1;k<n;k<<=1)
	{
		Complex wn = Complex(cos(pi/k),opt*sin(pi/k));
		for(int i=0;i<n;i+=(k<<1))
		{
			Complex w = Complex(1,0);
			for(int j=0;j<k;j++,w=w*wn)
			{
				Complex x = a[i+j],y = w*a[i+j+k];
				a[i+j] = x+y;
				a[i+j+k] = x-y;
			}
		}
	}
} 
void calc(int opt)
{
	FFT(a,1);
	FFT(b,1);
	for(int i=0;i<=n;i++) a[i]=a[i]*b[i];
	FFT(a,-1);
	for(int i=0;i<=n;i++) F[i] = (ll) (a[i].x/n+0.5)*opt;
	
}
int main()
{
	
	scanf("%d%d",&S,&T);
	S--,T--;
	scanf("%s%s",x,y);
	for(int i=0;i<=S;i++)
	{
		if(x[i]=='R') f[i][0] = 1.0;
		if(x[i]=='S') f[i][1] = 1.0;
		if(x[i]=='P') f[i][2] = 1.0;
	}
	for(int i=0;i<=T;i++)
	{
		if(y[i]=='R') g[T-i][1] = 1.0;
		if(y[i]=='S') g[T-i][2] = 1.0;
		if(y[i]=='P') g[T-i][0] = 1.0;
	}
//	for(int i=0;i<=T;i++) scanf("%lf",&g[i]);
	m=T+S; L=0;
	for(n=1;n<=m;n<<=1) L++;
	for(int i=0;i<n;i++) R[i] = (R[i>>1]>>1)|((i&1)<<(L-1));
	for(int kase=0;kase<3;kase++)
	{
		for(int i=0;i<=n;i++)
		{
			a[i]= Complex(1.0*f[i][kase],0.0);
			b[i]= Complex(1.0*g[i][kase],0.0);
		}
		calc(1);
		for(int i=0;i<=S+T;i++) {
			ans[i]+=F[i];
		//	printf("%lld ",F[i]);
		}
	//	printf("\n");
	}
	int allans=0;
	for(int i=T;i<=S+T;i++) allans= max(allans,ans[i]);
	printf("%d\n",allans); 
	return 0;
} 

/*
12 4
PPPRRRRRRRRR
RSSS

12 4
RRRRRRRRRSSS
RRRS



*/

http://www.niftyadmin.cn/n/1724490.html

相关文章

python网络编程取证_网络取证(Network Forensics)

网络取证(Network Forensics)现代网络环境的情况是&#xff0c;由于许多困难&#xff0c;调查可能充满困难。 无论您是在响应违规支持&#xff0c;调查内部活动&#xff0c;执行与漏洞相关的评估&#xff0c;还是验证法规遵从性&#xff0c;都可能发生这种情况。网络编程的概念…

2018 ICPC 焦作 E [大数+ 数论]

熟悉一下大数的板子 import java.util.Scanner; import java.math.*; public class Main {public static int [] prime new int [5001];public static int [] isprime new int [5001];public static int tot 0;public static void getprime(){isprime[1] 0;for(int i2;i<…

【Linux端口大全】

2端口&#xff1a;管理实用程序 3端口&#xff1a;压缩进程 5端口&#xff1a;远程作业登录 7端口&#xff1a;回显 9端口&#xff1a;丢弃 11端口&#xff1a;在线用户 13端口&#xff1a;时间 17端口&#xff1a;每日引用 18端口&#xff1a;消息发送协议 19端口&#xff1a;…

python unpack转化二进制文件_Python使用struct处理二进制(pack和unpack用法)

转载自&#xff1a;http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html这篇文章写的很好&#xff0c;所以无耻的转了。。有的时候需要用python处理二进制数据&#xff0c;比如&#xff0c;存取文件&#xff0c;socket操作时.这时候&#xff0c;可以使用python的stru…

python中nums.count()什么意思_python count返回什么

描述count() 方法用于统计字符串中某个子字符串出现的次数&#xff0c;可选参数为开始搜索与结束搜索的位置索引。语法count() 方法语法&#xff1a;S.count(sub[,start0[,endlen(S)]])参数sub -- 搜索的子字符串。S -- 父字符串。start -- 可选参数&#xff0c;字符串开始搜索…

设计模式系列 - 代理模式

通过创建现有对象的对象&#xff0c;以便向外界通过访问接口&#xff0c;这种模式我们称之为代理模式 介绍 代理模式属于结构型模式&#xff0c;通过在对象与对象之间添加一个代理中间层来到达对目标对象的间接访问。 类图描述 由上图可知&#xff0c;我们通过定义一个基本接口…

mysql数据库应用与开发姜桂洪 课后答案_数据库原理及MySQL_章节测验,期末考试,慕课答案查询公众号...

在合理情绪疗法的ABC理论中&#xff0c;A代表()。(A) 诱发事件(B) 理性信念(C) 不良情绪(D) 行为结果该求助者说“那我就不洗脸、不刷牙了。”&#xff0c;所表现的是()。(A) 意向下降(B) 兴趣减退(C) 意志减退(D) 习随访&#xff0c;定期复查A&#xff0e;子宫肌瘤如孕2个月大…

解读经典《C#高级编程》第七版 Page32-38.核心C#.Chapter2

前言 接下来讲讲预定义数据类型。关于数据类型&#xff0c;其实是非常值得透彻研究的。 01 预定义数据类型 值类型和引用类型 C#将把数据类型分为两种&#xff0c;值类型和引用类型&#xff0c;值类型存储在堆栈上&#xff0c;引用类型存储在托管堆上。因此&#xff0c;对于值类…