题链:

http://codevs.cn/problem/4158/

题解:

FFT。

定义两个相同长度的字符串s1,s2的距离为

$$dis(s1,s2)=\sum_{i=0}^{len-1}(s1[i]-s2[i])^2s1[i]s2[i]$$

如果两个字符串相同,那么dis=0。

(对于本题而言,只需把通配符用0表示,其它字符c用c-'a'+1表示。)

然后看看如何求出文本串T(长度为n)和模式串S(长度为m)的总共匹配数。

定义T串从$l$位置开始的长度为m的子串和S的距离为$D(l)$,那么:

$$D(l)=\sum_{k=0}^{m-1}(T[l+k]-S[k])^2T[l+k]S[k]$$

为了构成卷积形式,我们把S串翻转,即

$$D(l)=D'(l+m-1)=\sum_{k=0}^{m-1}(T[l+k]-S[m-1-k])^2T[l+k]S[m-1-k]$$

然而这个仍然不是卷积形式,我们再继续化一下式子:(令D(l)=D'(l+m-1))

$$\begin{aligned}
D'(l+m-1)&=\sum_{k=0}^{m-1}(T[l+k]-S[m-1-k])^2T[l+k]S[m-1-k]\\
&=\sum_{k=0}^{m-1}(T[l+k]^3S[m-1-k]-2T[l+k]^2S[m-1-k]^2+T[l+k]S[m-1-k]^3)\\
&=\sum_{k=0}^{m-1}T[l+k]^3S[m-1-k]+\sum_{k=0}^{m-1}-2T[l+k]^2S[m-1-k]^2+\sum_{k=0}^{m-1}T[l+k]S[m-1-k]^3
\end{aligned}$$

然后逮着这个式子做3组卷积即可。

代码:

#include<bits/stdc++.h>
#define MAXN 1048577
#define INF 0x3f3f3f3f
using namespace std;
const double Pi=acos(-1),eps=1e-6;
typedef complex<double>Complex;
Complex null(0,0);
int A[MAXN],B[MAXN],order[MAXN];
int idx(char ch){
if(ch=='*') return 0;
return ch-'a'+1;
}
void getstring(int *s,int len){
static char ch;
for(int i=0;i<len;i++)
scanf(" %c",&ch),s[i]=idx(ch);
}
void FFT(Complex *Y,int n,int sign){
for(int i=1;i<n;i++) if(i<order[i]) swap(Y[i],Y[order[i]]);
for(int d=2;d<=n;d<<=1){
Complex dw(cos(2*Pi/d),sin(sign*2*Pi/d)),w,tmp;
for(int i=0;w=Complex(1,0),i<n;i+=d)
for(int k=i;k<i+d/2;w=w*dw,k++)
tmp=w*Y[k+d/2],Y[k+d/2]=Y[k]-tmp,Y[k]=Y[k]+tmp;
}
}
int main(){
static int pos[MAXN];
static Complex f1[MAXN],g1[MAXN],f2[MAXN],g2[MAXN],f3[MAXN],g3[MAXN],D[MAXN];
int n,m,N,len,ans=0; scanf("%d%d",&n,&m);
getstring(A,n); getstring(B,m); reverse(A,A+n);
for(N=1,len=0;N<n+m-1;N<<=1) len++;
for(int i=1;i<N;i++) order[i]=(order[i>>1]>>1)|((i&1)<<(len-1));
for(int i=0;i<n;i++){
f1[i]=Complex(A[i]*A[i]*A[i],0);
f2[i]=Complex(A[i]*A[i],0);
f3[i]=Complex(A[i],0);
}
for(int i=0;i<m;i++){
g1[i]=Complex(B[i],0);
g2[i]=Complex(B[i]*B[i],0);
g3[i]=Complex(B[i]*B[i]*B[i],0);
}
FFT(f1,N,1); FFT(g1,N,1);
FFT(f2,N,1); FFT(g2,N,1);
FFT(f3,N,1); FFT(g3,N,1);
for(int i=0;i<N;i++) D[i]=f1[i]*g1[i]-2.0*f2[i]*g2[i]+f3[i]*g3[i];
FFT(D,N,-1);
for(int i=0;i<m-n+1;i++)
if((int)((D[i+n-1].real()+0.5)/N)==0) pos[++ans]=i+1;
printf("%d\n",ans);
for(int i=1;i<=ans;i++) printf("%d ",pos[i]);
printf("\n");
return 0;
}

  

●Codevs 4158 残缺的字符串的更多相关文章

  1. BZOJ 4259: 残缺的字符串 [FFT]

    4259: 残缺的字符串 题意:s,t,星号任意字符,匹配方案数 和上题一样 多乘上一个\(a_{j+i}\)就行了 #include <iostream> #include <cs ...

  2. 【BZOJ4259】残缺的字符串

    [BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时, ...

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

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

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

    [BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时, ...

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

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

  6. luoguP4173 残缺的字符串 FFT

    luoguP4173 残缺的字符串 FFT 链接 luogu 思路 和昨天做的题几乎一样. 匹配等价于(其实我更喜欢fft从0开始) \(\sum\limits_{i=0}^{m-1}(S[i+j]- ...

  7. 洛谷 P4173 残缺的字符串 (FFT)

    题目链接:P4173 残缺的字符串 题意 给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置. 思路 FFT 带有通配符的字符串匹配问题. 设模式串为 ...

  8. Luogu P4173 残缺的字符串-FFT在字符串匹配中的应用

    P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C ...

  9. P4173 残缺的字符串(FFT字符串匹配)

    P4173 残缺的字符串(FFT字符串匹配) P4173 解题思路: 经典套路将模式串翻转,将*设为0,设以目标串的x位置匹配结束的匹配函数为\(P(x)=\sum^{m-1}_{i=0}[A(m-1 ...

随机推荐

  1. 本地通知UILocalNotification

    1.增加一个本地推送 //设置20秒之后  ]; //chuagjian一个本地推送 UILocalNotification *noti = [[[UILocalNotification alloc] ...

  2. httpClient解决post请求重定向的问题

    import com.dadi.saas.util.HTTPUtils; import org.apache.commons.httpclient.Header; import org.apache. ...

  3. CentOS7.4下的 JDK1.8 安装

    一.卸载老的JDK 如果需要卸载OpenJDK,执行以下操作: [root@localhost ~]# rpm -e --nodeps tzdata-java-2014i-1.el7.noarch[r ...

  4. spring7——AOP之通知和顾问

    通知和顾问都是切面的实现形式,其中通知可以完成对目标对象方法简单的织入功能. 而顾问包装了通知,可以让我们对通知实现更加精细化的管理,让我们可以指定具体的切入点. 通知分为前置通知,环绕通知及后置通知 ...

  5. python、java实现二叉树,细说二叉树添加节点、深度优先(先序、中序、后续)遍历 、广度优先 遍历算法

    数据结构可以说是编程的内功心法,掌握好数据结构真的非常重要.目前基本上流行的数据结构都是c和c++版本的,我最近在学习python,尝试着用python实现了二叉树的基本操作.写下一篇博文,总结一下, ...

  6. WKWebView使用

    WKWebView比之之前使用的UIWebView更加具有优势,UIWebView更加的笨重,UIWebView占用更多的内存,且内存的峰值更加的夸张,WKWebView加载的速度也更快,而且其更多的 ...

  7. awk、变量、运算符、if多分支

    awk.变量.运算符.if多分支 awk: 语法 awk [options] 'commands' files option -F 定义字段分隔符,默认的分隔符是连续的空格或制表符 使用option中 ...

  8. python打包压缩文件夹zip+组装文件夹

    无意间想到的一个需求,然后就顺手写了写,留下来,方便以后用 列表版:(基本没用,仅提供思路,字典版稍微改动可以直接用) 大体需求: 把重复的文件名进行改名,达到浏览器下载相同文件的效果 下载完成后再把 ...

  9. Zookeeper通过java创建、查看、修改、删除znode

    本章主要介绍zookeeper如何使用,其实通过zkCli.cmd我们是可以执行一些操作的:声明:参考及转自<http://www.blogjava.net/BucketLi/archive/2 ...

  10. 01、NetCore2.0优化之Web服务器 与 IIS解耦

    01.NetCore2.0优化之Web服务器 与 IIS解耦 在Asp.Net Core 2.0中,是如何实现跨平台的?不使用IIS了,在linux上的WebServer是什么? ---------- ...