快速傅里叶变换(FFT):COGS 2216. 你猜是不是KMP
2216. 你猜是不是KMP
★★★☆ 输入文件:guess.in 输出文件:guess.out 简单对比
时间限制:1 s 内存限制:256 MB
【题目描述】
XX在玩两个串的游戏。首先,他拿出了两个字符串 S 和 T,XX想知道 T在 S 中出现了几次,分别在哪些位置出现。注意 T 中可能有“?”字符,这个字符可以匹配任何字符。
【输入格式】
两行两个字符串,分别代表 S 和 T
【输出格式】
第一行一个正整数 k,表示 T 在 S 中出现了几次。
接下来 k 行正整数,
分别代表 T 每次在 S 中出现的开始位置。按照从小到大
的顺序输出,S 下标从 0 开始。
【样例输入】
ababcadaca
a?a
【样例输出】
3
0
5
7
【提示】
对于 10%的数据, S 和 T 的长度不超过 100
对于另外 20%的数据,T 中无“?”
对于 100%的数据,S 长度不超过 10^5,T 长度不会超过 S。S 中只包含小写
字母,T 中只包含小写字母和“?”
【来源】
经典题目
这道题咩,是FFT哦,咳咳……
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn=;
const double PI=acos(-1.0);
char s[maxn],t[maxn];
int a[maxn],b[maxn];
struct complex{
double r,i;
complex(double r_=0.0,double i_=0.0){
r=r_;i=i_;
}
complex operator +(complex a){
return complex(r+a.r,i+a.i);
}
complex operator -(complex a){
return complex(r-a.r,i-a.i);
}
complex operator *(complex a){
return complex(r*a.r-i*a.i,r*a.i+i*a.r);
}
};
complex A[maxn],B[maxn],C[maxn],D[maxn],E[maxn]; void Rader(complex *a,int len){
int k;
for(int i=,j=len>>;i<len-;i++){
if(i<j)swap(a[i],a[j]);
k=len>>;
while(j>=k){
j-=k;
k>>=;
}
j+=k;
}
} void FFT(complex *a,int len,int on){
Rader(a,len);
for(int h=;h<=len;h<<=){
complex wn(cos(-on*PI*2.0/h),sin(-on*PI*2.0/h));
for(int j=;j<len;j+=h){
complex w(,);
for(int k=j;k<j+(h>>);k++){
complex u=a[k];
complex v=a[k+(h>>)]*w;
a[k]=u+v;
a[k+(h>>)]=u-v;
w=w*wn;
}
}
}
if(on==-)
for(int i=;i<len;i++)
a[i].r/=len;
}
int ans[maxn],tot;
int main(){
freopen("guess.in","r",stdin);
freopen("guess.out","w",stdout);
scanf("%s%s",s,t);
int lens=strlen(s);
int lent=strlen(t);
for(int i=;i<lens;i++)
a[i]=s[i]-'a'+;
for(int i=;i<lent;i++){
if(t[i]=='?')
b[lent-i-]=;
else
b[lent-i-]=t[i]-'a'+;
} int len=;
while(len<=lens+lent)len<<=; for(int i=;i<lens;i++)A[i]=complex(1.0,);
for(int i=;i<lent;i++)B[i]=complex(1.0*b[i]*b[i]*b[i],);
FFT(A,len,);FFT(B,len,);
for(int i=;i<len;i++)C[i]=A[i]*B[i];
FFT(C,len,-); memset(A,,sizeof(A));
memset(B,,sizeof(B));
for(int i=;i<lens;i++)A[i]=complex(2.0*a[i],);
for(int i=;i<lent;i++)B[i]=complex(1.0*b[i]*b[i],);
FFT(A,len,);FFT(B,len,);
for(int i=;i<len;i++)D[i]=A[i]*B[i];
FFT(D,len,-); memset(A,,sizeof(A));
memset(B,,sizeof(B));
for(int i=;i<lens;i++)A[i]=complex(1.0*a[i]*a[i],);
for(int i=;i<lent;i++)B[i]=complex(1.0*b[i],);
FFT(A,len,);FFT(B,len,);
for(int i=;i<len;i++)E[i]=A[i]*B[i];
FFT(E,len,-); for(int i=lent-;i<lens;i++)
if(fabs(C[i].r-D[i].r+E[i].r)<1e-)
ans[++tot]=i-lent+; printf("%d\n",tot);
for(int i=;i<=tot;i++)
printf("%d\n",ans[i]);
return ;
}
快速傅里叶变换(FFT):COGS 2216. 你猜是不是KMP的更多相关文章
- [学习笔记] 多项式与快速傅里叶变换(FFT)基础
引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...
- 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】
原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...
- 快速傅里叶变换FFT
多项式乘法 #include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib ...
- 快速傅里叶变换FFT& 数论变换NTT
相关知识 时间域上的函数f(t)经过傅里叶变换(Fourier Transform)变成频率域上的F(w),也就是用一些不同频率正弦曲线的加 权叠加得到时间域上的信号. \[ F(\omega)=\m ...
- 快速傅里叶变换(FFT)
扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...
- 快速傅里叶变换(FFT)_转载
FFTFFT·Fast Fourier TransformationFast Fourier Transformation快速傅立叶变换 P3803 [模板]多项式乘法(FFT) 参考上文 首 ...
- 基于python的快速傅里叶变换FFT(二)
基于python的快速傅里叶变换FFT(二)本文在上一篇博客的基础上进一步探究正弦函数及其FFT变换. 知识点 FFT变换,其实就是快速离散傅里叶变换,傅立叶变换是数字信号处理领域一种很重要的算法. ...
- 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理
浅谈范德蒙德(Vandermonde)方阵的逆矩阵与拉格朗日(Lagrange)插值的关系以及快速傅里叶变换(FFT)中IDFT的原理 标签: 行列式 矩阵 线性代数 FFT 拉格朗日插值 只要稍微看 ...
- 快速傅里叶变换FFT / NTT
目录 FFT 系数表示法 点值表示法 复数 DFT(离散傅里叶变换) 单位根的性质 FFT(快速傅里叶变换) IFFT(快速傅里叶逆变换) NTT 阶 原根 扩展知识 FFT 参考blog: 十分简明 ...
随机推荐
- svs 在创建的时候 上传文件夹 bin obj 这些不要提交
svs 在创建的时候 上传文件夹 bin obj 这些不要提交 右键-去除版本控制并增加到忽略列表
- Java开发工程师必会做试题
一.单选题 (共19道题,每题5分) 1.下面有关java的一些细节问题,描述错误的是? A.构造方法不需要同步化 B.一个子类不可以覆盖掉父类的同步方法 C.定义在接口中的方法默认是publ ...
- jdbc - Insert 'Date' value in PreparedStatement
“preparedStatement.setDate()”方法接受的是 'java.sql.Date' 类型的参数,而我们一般格式化日期所使用的是'java.util.Date'中的'SimpleDa ...
- 使用EasyUI导入的js顺序
使用Jquery Easy UI要导入的js顺序<1>.引用Jquery的Js文件<script src="jquery-easyui-1.3.4/jquery-1.8.0 ...
- js编译和执行顺序
JS是一段一段执行的(以<script>标签来分割),执行每一段之前,都有一个“预编译”,预编译干的活是:声明所有var变量(初始为undefined),解析定义式函数语句. 还有个关于 ...
- topcoder算法练习3
SRM144 DIV1 1100 point Problem Statement NOTE: There are images in the examples section of this ...
- UILongPressGestureRecognizer的selector多次调用解决方法
当你使用longPress gesture recognizer 时,你可能会发现调用了多次. UILongPressGestureRecognizer *longPress = [[UILongPr ...
- WARN [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED
问题描述:hive 关于告警问题的解决:WARN [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED: Config ...
- zoj3839-Poker Face
#include<cstdio>int n;void P(int i,int j,int n,int f){ if(i==n){ for(int k=1;k<=n;k++)print ...
- window 配置 sendmail
从http://glob.com.au/sendmail/下载sendmail.zip 解压sendmail.zip到目录下(最好使用短路径,长路径会导致问题的出现),我安装的路径是: E:\wamp ...