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的更多相关文章

  1. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  2. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

  3. 快速傅里叶变换FFT

    多项式乘法 #include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib ...

  4. 快速傅里叶变换FFT& 数论变换NTT

    相关知识 时间域上的函数f(t)经过傅里叶变换(Fourier Transform)变成频率域上的F(w),也就是用一些不同频率正弦曲线的加 权叠加得到时间域上的信号. \[ F(\omega)=\m ...

  5. 快速傅里叶变换(FFT)

    扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...

  6. 快速傅里叶变换(FFT)_转载

    FFTFFT·Fast  Fourier  TransformationFast  Fourier  Transformation快速傅立叶变换 P3803 [模板]多项式乘法(FFT) 参考上文 首 ...

  7. 基于python的快速傅里叶变换FFT(二)

    基于python的快速傅里叶变换FFT(二)本文在上一篇博客的基础上进一步探究正弦函数及其FFT变换. 知识点  FFT变换,其实就是快速离散傅里叶变换,傅立叶变换是数字信号处理领域一种很重要的算法. ...

  8. 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理

    浅谈范德蒙德(Vandermonde)方阵的逆矩阵与拉格朗日(Lagrange)插值的关系以及快速傅里叶变换(FFT)中IDFT的原理 标签: 行列式 矩阵 线性代数 FFT 拉格朗日插值 只要稍微看 ...

  9. 快速傅里叶变换FFT / NTT

    目录 FFT 系数表示法 点值表示法 复数 DFT(离散傅里叶变换) 单位根的性质 FFT(快速傅里叶变换) IFFT(快速傅里叶逆变换) NTT 阶 原根 扩展知识 FFT 参考blog: 十分简明 ...

随机推荐

  1. svs 在创建的时候 上传文件夹 bin obj 这些不要提交

    svs  在创建的时候 上传文件夹 bin  obj  这些不要提交  右键-去除版本控制并增加到忽略列表

  2. Java开发工程师必会做试题

    一.单选题     (共19道题,每题5分) 1.下面有关java的一些细节问题,描述错误的是? A.构造方法不需要同步化 B.一个子类不可以覆盖掉父类的同步方法 C.定义在接口中的方法默认是publ ...

  3. jdbc - Insert 'Date' value in PreparedStatement

    “preparedStatement.setDate()”方法接受的是 'java.sql.Date' 类型的参数,而我们一般格式化日期所使用的是'java.util.Date'中的'SimpleDa ...

  4. 使用EasyUI导入的js顺序

    使用Jquery Easy UI要导入的js顺序<1>.引用Jquery的Js文件<script src="jquery-easyui-1.3.4/jquery-1.8.0 ...

  5. js编译和执行顺序

    JS是一段一段执行的(以<script>标签来分割),执行每一段之前,都有一个“预编译”,预编译干的活是:声明所有var变量(初始为undefined),解析定义式函数语句. 还有个关于 ...

  6. topcoder算法练习3

    SRM144 DIV1 1100 point Problem Statement      NOTE: There are images in the examples section of this ...

  7. UILongPressGestureRecognizer的selector多次调用解决方法

    当你使用longPress gesture recognizer 时,你可能会发现调用了多次. UILongPressGestureRecognizer *longPress = [[UILongPr ...

  8. WARN [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED

    问题描述:hive 关于告警问题的解决:WARN  [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED: Config ...

  9. 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 ...

  10. window 配置 sendmail

    从http://glob.com.au/sendmail/下载sendmail.zip 解压sendmail.zip到目录下(最好使用短路径,长路径会导致问题的出现),我安装的路径是: E:\wamp ...