BZOJ 4503 两个串 ——FFT
【题目分析】
定义两个字符之间的距离为
(ai-bi)^2*ai*bi
如果能够匹配,从i到i+m的位置的和一定为0
但这和暴力没有什么区别。
发现把b字符串反过来就可以卷积用FFT了。
听说KMP+暴力可以卡到100ms以内(雾)
【代码】
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; #define maxn 400005
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i) const double pi=acos(-1.0);
const double eps=1e-6; struct Complex{
double x,y;
Complex operator + (Complex a) const{Complex b; return b.x=x+a.x,b.y=y+a.y,b;}
Complex operator - (Complex a) const{Complex b; return b.x=x-a.x,b.y=y-a.y,b;}
Complex operator * (Complex a) const{Complex b; return b.x=x*a.x-y*a.y,b.y=x*a.y+y*a.x,b;}
}a[maxn],b[maxn],c[maxn]; char s[maxn],t[maxn];
int A[maxn],B[maxn];
int ls,lt,rev[maxn],n,m=1,len,ans[maxn]; void FFT(Complex * x, int n, int f)
{
F(i,0,n-1) if (rev[i]>i) swap(x[rev[i]],x[i]);
for (int m=2;m<=n;m<<=1)
{
int mid=m>>1;Complex wn; wn.x=cos(2.0*pi/m*f); wn.y=sin(2.0*pi/m*f);
for (int i=0;i<n;i+=m)
{
Complex w; w.x=1.0; w.y=0;
F(j,0,mid-1)
{
Complex a=x[i+j],b=x[i+j+mid]*w;
x[i+j]=a+b; x[i+j+mid]=a-b;
w=w*wn;
}
}
}
} int main()
{
// freopen("in.txt","r",stdin);
scanf("%s",s); scanf("%s",t);
ls=strlen(s); lt=strlen(t);
n=ls+lt+1;
while (m<=n) m<<=1,len++; n=m;
F(i,0,n-1)
{
int t=i,ret=0;
F(j,1,len) ret<<=1,ret|=t&1,t>>=1;
rev[i]=ret;
}
F(i,0,ls-1) A[i]=s[i]-'a'+1;
F(i,0,lt-1) {B[lt-i-1]=t[i]-'a'+1;if (t[i]=='?') B[lt-i-1]=0;} memset(a,0,sizeof a);
memset(b,0,sizeof b);
F(i,0,n-1) a[i].x=1;
F(i,0,n-1) b[i].x=B[i]*B[i]*B[i];
FFT(a,n,1); FFT(b,n,1);
F(i,0,n-1)
c[i]=a[i]*b[i]; memset(a,0,sizeof a);
memset(b,0,sizeof b);
F(i,0,n-1) a[i].x=2*A[i];
F(i,0,n-1) b[i].x=B[i]*B[i];
FFT(a,n,1); FFT(b,n,1);
F(i,0,n-1)
c[i]=c[i]-a[i]*b[i]; memset(a,0,sizeof a);
memset(b,0,sizeof b);
F(i,0,n-1) a[i].x=A[i]*A[i];
F(i,0,n-1) b[i].x=B[i];
FFT(a,n,1); FFT(b,n,1);
F(i,0,n-1) c[i]=c[i]+a[i]*b[i]; FFT(c,n,-1);
F(i,0,n-1) c[i].x=c[i].x/n;
int cnt=0;
F(i,0,ls-lt) if (c[i+lt-1].x<0.5) cnt++;
printf("%d\n",cnt);
F(i,0,ls-lt) if (c[i+lt-1].x<0.5) printf("%d\n",i);
}
BZOJ 4503 两个串 ——FFT的更多相关文章
- BZOJ 4503: 两个串 [FFT]
4503: 两个串 题意:兔子们在玩两个串的游戏.给定两个只含小写字母的字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有"?"字符,这个字符可以匹 ...
- BZOJ.4503.两个串(FFT/bitset)
题目链接 \(Description\) 给定两个字符串S和T,求T在S中出现了几次,以及分别在哪些位置出现.T中可能有'?'字符,这个字符可以匹配任何字符. \(|S|,|T|\leq 10^5\) ...
- bzoj 4503 两个串——FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4503 翻转T,就变成卷积.要想想怎么判断. 因为卷积是乘积求和,又想到相等的话相减为0,所以 ...
- bzoj 4503 两个串 —— FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4503 推式子即可: 不知怎的调了那么久,应该是很清晰的. 代码如下: #include< ...
- bzoj 4503 两个串
Description 兔子们在玩两个串的游戏.给定两个字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有“?”字符,这个字符可以匹配任何字符. Input 两行两个字 ...
- 【刷题】BZOJ 4503 两个串
Description 兔子们在玩两个串的游戏.给定两个字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有"?"字符,这个字符可以匹配任何字符. I ...
- BZOJ 4503 两个串(FFT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4503 [题目大意] 给出S串和T串,计算T在S中出现次数,T中有通配符'?'. [题解 ...
- bzoj 4503 两个串 快速傅里叶变换FFT
题目大意: 给定两个\((length \leq 10^5)\)的字符串,问第二个串在第一个串中出现了多少次.并且第二个串中含有单字符通配符. 题解: 首先我们从kmp的角度去考虑 这道题从字符串数据 ...
- bzoj 4503: 两个串【脑洞+FFT】
真实脑洞题 因为通配符所以导致t串实际有指数级别个,任何字符串相关算法都没有用 考虑一个新的匹配方法:设a串(模板串)长为n,从m串的i位置开始匹配:\( \sum_{i=0}^{n-1}(a[j]- ...
随机推荐
- sqlserver数据库备份方法
须事先准备一个工具curl,把它放在c盘.然后,在数据库所在服务器安装7z.最后把这2个存储过程执行,在sqlserver的代理中新建作业,即可实现备份操作. --备份指定数据库到本地和远程指定位置( ...
- 如何计算支撑向量数(SVs)
申明:转载请注明出处. 支持向量机(SVM)是一个成熟的单分类器,常常用于对比实验中.往往需要统计支持向量数量来比较算法优劣,MATLAB有自带的SVM工具箱,用法如下: [train, test] ...
- navicate与mysql连接的中文乱码问题
1. 在navicate中查看 show variables like'char%'; show variables like 'collation_%'; 2.在mysql中查看 通过对比可以发现两 ...
- 分享一个WebGL开发的网站-用JavaScript + WebGL开发3D模型
这张图每位程序员应该都深有感触. 人民心目中的程序员是这样的:坐在电脑面前噼里啪啦敲着键盘,运键如飞. 现实中程序员是这样的:编码5分钟,调试两小时. 今天我要给大家分享一个用WebGL开发的网站,感 ...
- 实用IMX6开发板来袭, 方便开发板方便你
这是迅为电子推出的一款IMX6Q开发板是Freescale Cortex-a9四核处理器,采用底板加核心板形式,稳定耐用,拆卸非常的方便,同一底板兼容四种核心板,分别为四核商业级,四核工业级,双核商业 ...
- hdu 1181 深搜
中文题 深搜 许久没写鸟,卡在输入问题上... #include <iostream> #include <string> using namespace std; bool ...
- 第009课 gcc和arm-linux-gcc和MakeFile
from:第009课 gcc和arm-linux-gcc和MakeFile 第001节_gcc编译器1_gcc常用选项_gcc编译过程详解 gcc的使用方法 gcc [选项] 文件名 gcc常用选项 ...
- ssh的server安装和安装指定版本的软件的方法
ssh程序分为有客户端程序openssh-client和服务端程序openssh-server.如果需要ssh登陆到别的电脑,需要安装openssh-client,该程序ubuntu是默认安装的.而如 ...
- 字符串数组 输入3个字符串,要求按由小到大的字母顺序输出; 输入n个学生的姓名和学号到字符串数组中,在输入一个姓名,如果班级有该生则返回其信息,否则返回本班无此人
输入3个字符串,要求按由小到大的字母顺序输出 如 输入franch england china,输出结果是china england franch 三个数排序输出,比较三个数的大小怎么做? a=18 ...
- 初涉倍增&&LCA【在更】
一种特殊的枚举算法 什么是倍增 顾名思义,即每一次翻倍增加.那么,这样我们就有了一种$O(logn)$阶的方法处理枚举方面的问题了. 参考:[白话系列]倍增算法 一些题目 [倍增]luoguP1613 ...