原文链接http://www.cnblogs.com/zhouzhendong/p/8798532.html

题目传送门 - BZOJ4259

题意

  给你两个串,用其中一个来匹配另一个。问从母串的那些位置开始可以匹配模式串。注意有"*"可以匹配任何字符。

  串长$\leq 3\times 10^5$。

题解

  本题和BZOJ4503几乎一毛一样。

  这里直接放BZOJ4503的传送门。
  http://www.cnblogs.com/zhouzhendong/p/8536065.html

  但是这题要略微卡一卡时间和空间。

  这题让我第一次感受到了寻址的效率之慢。

  通过测试,同样是访问大约$8400000$个地址,仅通过改变访问顺序,我可以测出最快访问速度大约13倍的最慢访问速度。就是通过改变访问$8400000$个位置的顺序,使得$460MS\rightarrow 5500MS$(谢谢BZOJ测评器,如果我选紫荆花之恋来测试的话可能得到的数据会更好哈哈,但我不敢)。(但这个应该不是上限)

  真的是QAQ。

  我写的$FFT$中对$w_{t\times j}$的寻址特别慢,所以导致效率慢了约$3000MS$。写成$Claris$的写法,可以把我的程序卡到$5000MS$(虽然精度会稍微差一点但是可以承受)。

代码

#include <bits/stdc++.h>
#define y1 ______y1
using namespace std;
typedef long long LL;
const int N=1<<20;
const double PI=acos(-1.0);
int n,L,R[N];
struct C{
double r,i;
C(){}
C(double a,double b){r=a,i=b;}
C operator + (C x){return C(r+x.r,i+x.i);}
C operator - (C x){return C(r-x.r,i-x.i);}
C operator * (C x){return C(r*x.r-i*x.i,r*x.i+i*x.r);}
void operator = (double x){r=x,i=0;}
}w[N],x1[N],x2[N],y1[N],y2[N],z[N];
int L1,L2,a[N],b[N];
LL res[N];
char s1[N],s2[N];
void FFT(C a[]){
for (int i=0;i<n;i++)
if (i<R[i])
swap(a[i],a[R[i]]);
for (int t=n>>1,d=1;d<n;d<<=1,t>>=1)
for (int i=0;i<n;i+=(d<<1))
for (int j=0,prod=0;j<d;j++,prod+=t){
C tmp=w[prod]*a[i+j+d];
a[i+j+d]=a[i+j]-tmp;
a[i+j]=a[i+j]+tmp;
}
}
int ans[N],acnt=0;
int main(){
scanf("%d%d%s%s",&L2,&L1,s2,s1);
for (int i=0;i<L2/2;i++)
swap(s2[i],s2[L2-i-1]);
for (int i=0;i<L1;i++)
a[i]=s1[i]=='*'?0:(s1[i]-'a'+1);
for (int i=0;i<L2;i++)
b[i]=s2[i]=='*'?0:(s2[i]-'a'+1);
for (n=1,L=0;n<L1+L2;n<<=1,L++);
for (int i=0;i<n;i++){
R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
w[i]=C(cos(2*i*PI/n),sin(2*i*PI/n));
}
memset(res,0,sizeof res);
for (int i=0;i<n;i++){
x1[i]=1.0*a[i]*a[i]*a[i],y1[i]=1.0*b[i];
x2[i]=1.0*a[i]*a[i],y2[i]=1.0*b[i]*b[i];
}
FFT(x1),FFT(x2),FFT(y1),FFT(y2);
for (int i=0;i<n;i++){
z[i]=x1[i]*y1[i]-C(2.0,0)*x2[i]*y2[i];
x1[i]=1.0*a[i],y1[i]=1.0*b[i]*b[i]*b[i];
}
FFT(x1),FFT(y1);
for (int i=0;i<n;i++){
z[i]=z[i]+x1[i]*y1[i];
w[i].i*=-1.0;
}
FFT(z);
for (int i=0;i<n;i++)
res[i]=(LL)(z[i].r/n+0.5);
for (int i=L2-1;i<L1;i++)
if (res[i]==0)
ans[++acnt]=i-L2+2;
printf("%d\n",acnt);
for (int i=1;i<=acnt;i++)
printf("%d ",ans[i]);
return 0;
}

  

BZOJ4259 残缺的字符串 多项式 FFT的更多相关文章

  1. BZOJ4259 残缺的字符串 【fft】

    题目 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想 ...

  2. BZOJ4259 残缺的字符串(FFT)

    两个串匹配时相匹配的位置位置差是相同的,那么翻转一个串就变成位置和相同,卷积的形式. 考虑如何使用卷积体现两个位置能否匹配.一个暴力的思路是每次只考虑一种字符,将其在一个串中设为1,并在另一个串中将不 ...

  3. 2018.11.17 bzoj4259: 残缺的字符串(fft)

    传送门 fftfftfft套路题. 我们把aaa ~ zzz映射成111 ~ 262626,然后把∗*∗映射成000. 考虑对于两个长度都为nnn的字符串A,BA,BA,B. 我们定义一个差异函数di ...

  4. 【BZOJ4259】残缺的字符串(FFT)

    [BZOJ4259]残缺的字符串(FFT) 题面 给定两个字符串\(|S|,|T|\),两个字符串中都带有通配符. 回答\(T\)在\(S\)中出现的次数. \(|T|,|S|<=300000\ ...

  5. CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串

    Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...

  6. BZOJ4259:残缺的字符串(FFT)

    Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...

  7. BZOJ4259:残缺的字符串(FFT与字符串匹配)

    很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想对这两 ...

  8. BZOJ4259: 残缺的字符串(FFT 字符串匹配)

    题意 题目链接 Sol 知道FFT能做字符串匹配的话这就是个裸题了吧.. 考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = ...

  9. BZOJ4259残缺的字符串

    题目描述 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. ...

随机推荐

  1. 查看Android系统已安装应用的列表

    可以通过adb shell pm list package 我们可以通过系统提供的工具pm来隐藏一些应用,比如:pm hide和pm disable pm disable <PACKAGE_OR ...

  2. [Codeforces702F]T-Shirts——非旋转treap+贪心

    题目链接: Codeforces702F 题目大意:有$n$种T恤,每种有一个价格$c_{i}$和品质$q_{i}$且每种数量无限.现在有$m$个人,第$i$个人有$v_{i}$元,每人每次会买他能买 ...

  3. 高斯消元(Gauss消元)

    众所周知,高斯消元可以用来求n元一次方程组的,主要思想就是把一个n*(n+1)的矩阵的对角线消成1,除了第n+1列(用来存放b的)的其他全部元素消成0,是不是听起来有点不可思议??! NO NO NO ...

  4. webpack学习记录 - 学习webpack-dev-server(三)

    怎么用最简单的方式搭建一个服务器? 首先安装插件 npm i --save-dev webpack-dev-server 然后修改 packet.json 文件 "scripts" ...

  5. CF1120D(神奇的构造+最小生成树)

    考虑把树展开,单独把叶子节点拿出来 于是可以把控制点\(x\)的,抽象成是在它叶子节点间连权值为\(c_x\)的边 显然只用在\(x\)子树的最左边的叶子节点和最右边的叶子节点的下一个节点连边(最后一 ...

  6. 用不用lambda,这是一个问题

    用不用lambda,这是一个问题  mp.weixin.qq.com Sun在2009年开启了代号为“dolphin”的工程,计划在JDK1.7中加入lambda表达式.虚拟机模块化支持.动态语言支持 ...

  7. 解决远程连接MongoDB出现错误

    前言:最近准备学习下MongoDB,安装什么的都已经弄完了,想远程连接来管理MongoDB,用的软件是robo 3t 第一次连的时候就出错误了 大概意思是连接失败,解决如下 第一步,首先检查你的服务器 ...

  8. Python:正则表达式详解

    正则表达式是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,作为一个爬虫工作者,每天和字符串打交道,正则表达式更是不可或缺的技能,正则表达式的在不同的语言中使用方式可能 ...

  9. openstack项目【day23】:Neutron实现网络虚拟化

    本节内容 一 Neutron概述 二 neutron openvswitch+gre/vxlan虚拟网络 三 neutron ovs opnflow流表和l2 population 四 dhcp ag ...

  10. [Android] Android 锁屏实现与总结 (一)

    实现锁屏的方式有多种(锁屏应用.悬浮窗.普通Activity伪造锁屏等等).但国内比较主流并且被广泛应用的Activity伪造锁屏方式. 实例演示图片如下: 系列文章链接如下: [Android] A ...