BZOJ4259:残缺的字符串——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4259
很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n。可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺。你想对这两个串重新进行匹配,其中A为模板串,那么现在问题来了,请回答,对于B的每一个位置i,从这个位置开始连续m个字符形成的子串是否可能与A串完全匹配?
跟随胡神犇的步伐先把前置技能学了。
参考:https://www.cnblogs.com/clrs97/p/4814499.html
kmp是不行的,而作为一道套路题,我们有一定的套路:暴力匹配!
先默认字符串是以0开头的,方便我们后来FFT。
设dis(A,B)=(A-B)*[A!='*']*[B!='*']表示了AB字符是否相等,如果相等则答案为0。
于是我们把*字符看做0,则直接变成dis(A,B)=(A-B)AB。
设f[i]为B串以i为终点,往前与A匹配是否能匹配上。
显然就是dis累加的过程,只要最终f[i]=0就说明i-n+2是一个合法解。
然后你就会发现这个dis累加拆开之后很像卷积啊。
于是把A数组倒过来然后后面补齐0(即*字符),你就会发现实际上这就是三个卷积。
于是我们(不)愉快的写了个FFT并且AC。
(式子推导就看参考吧……心情不好不想写数学公式)
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef double dl;
const dl pi=acos(-1.0);
const dl eps=0.5;
const int N=2e6+;
struct complex{
dl x,y;
complex(dl xx=0.0,dl yy=0.0){
x=xx;y=yy;
}
complex operator +(const complex &b)const{
return complex(x+b.x,y+b.y);
}
complex operator -(const complex &b)const{
return complex(x-b.x,y-b.y);
}
complex operator *(const complex &b)const{
return complex(x*b.x-y*b.y,x*b.y+y*b.x);
}
};
void FFT(complex a[],int n,int on){
for(int i=,j=n>>;i<n-;i++){
if(i<j)swap(a[i],a[j]);
int k=n>>;
while(j>=k){j-=k;k>>=;}
if(j<k)j+=k;
}
for(int i=;i<=n;i<<=){
complex res(cos(-on**pi/i),sin(-on**pi/i));
for(int j=;j<n;j+=i){
complex w(,);
for(int k=j;k<j+i/;k++){
complex u=a[k],t=w*a[k+i/];
a[k]=u+t;a[k+i/]=u-t;
w=w*res;
}
}
}
if(on==-)
for(int i=;i<n;i++)a[i].x/=n;
}
int n,m,a[N],b[N];
complex f[N],A[N],B[N];
char s1[N],s2[N];
int main(){
scanf("%d%d%s%s",&n,&m,s1,s2);
for(int i=,j=n-;i<j;i++,j--)swap(s1[i],s1[j]);
for(int i=;i<n;i++){
if(s1[i]!='*')a[i]=s1[i]-'a'+;
else a[i]=;
}
for(int i=;i<m;i++){
if(s2[i]!='*')b[i]=s2[i]-'a'+;
else b[i]=;
}
int len=;
while(len<m)len<<=; for(int i=;i<len;i++)
A[i]=complex(a[i]*a[i]*a[i],),B[i]=complex(b[i],);
FFT(A,len,);FFT(B,len,);
for(int i=;i<len;i++)f[i]=f[i]+A[i]*B[i]; for(int i=;i<len;i++)
A[i]=complex(a[i]*a[i],),B[i]=complex(b[i]*b[i],);
FFT(A,len,);FFT(B,len,);
for(int i=;i<len;i++)f[i]=f[i]-A[i]*B[i]*complex(,); for(int i=;i<len;i++)
A[i]=complex(a[i],),B[i]=complex(b[i]*b[i]*b[i],);
FFT(A,len,);FFT(B,len,);
for(int i=;i<len;i++)f[i]=f[i]+A[i]*B[i]; FFT(f,len,-);
int ans=;
for(int i=n-;i<m;i++)if(f[i].x<eps)ans++;
printf("%d\n",ans);
if(ans){
for(int i=n-;i<m;i++)if(f[i].x<eps)printf("%d ",i-n+);
puts("");
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ4259:残缺的字符串——题解的更多相关文章
- CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串
Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...
- BZOJ4259残缺的字符串
题目描述 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. ...
- BZOJ4259 残缺的字符串 【fft】
题目 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想 ...
- BZOJ4259: 残缺的字符串 & BZOJ4503: 两个串
[传送门:BZOJ4259&BZOJ4503] 简要题意: 给出两个字符串,第一个串长度为m,第二个串长度为n,字符串中如果有*字符,则代表当前位置可以匹配任何字符 求出第一个字符串在第二个字 ...
- BZOJ4259 残缺的字符串 多项式 FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8798532.html 题目传送门 - BZOJ4259 题意 给你两个串,用其中一个来匹配另一个.问从母串的那些 ...
- BZOJ4259 残缺的字符串(FFT)
两个串匹配时相匹配的位置位置差是相同的,那么翻转一个串就变成位置和相同,卷积的形式. 考虑如何使用卷积体现两个位置能否匹配.一个暴力的思路是每次只考虑一种字符,将其在一个串中设为1,并在另一个串中将不 ...
- BZOJ4259:残缺的字符串(FFT)
Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...
- [BZOJ4259]残缺的字符串
Description: 给定两个带通配符的串,求可能出现几次匹配,以及这些匹配位置 Hint: \(n \le 3*10^5\) Solution: 定义匹配函数 \(P(x)=\sum_{i=x} ...
- 2018.11.17 bzoj4259: 残缺的字符串(fft)
传送门 fftfftfft套路题. 我们把aaa ~ zzz映射成111 ~ 262626,然后把∗*∗映射成000. 考虑对于两个长度都为nnn的字符串A,BA,BA,B. 我们定义一个差异函数di ...
随机推荐
- L010 linux命令及基础手把手实战总结
一转眼都快两周没更新了,最近实在太忙了,这两周的时间断断续续的把L010学完了,短短的15节课,确是把前10节的课程全部的运用一遍,从笔记到整理,再到重新理解,最后发布到微博,也确实提升了一些综合性能 ...
- Unity Container中的几种注册方式与示例
1.实例注册 最简单的注册方式就是实例注册,Unity 容器负责维护对一个类型的单例引用,比如: 有如下的实际类型: namespace ConsoleSample { public class Sa ...
- define的误用
#define LIGHT_SPEED 3e8 // m/sec (in a vacuum)
- android分析windowManager、window、viewGroup之间关系(二)
三.接上一节,分析windowManager中添加一个悬浮框的方式,首先看代码 WindowManager.LayoutParams params = new LayoutParams(); para ...
- JVM学习--jvm监控和故障处理工具
java虚拟机性能监控常用命令 Sun JDK监控和故障处理命令有jps.jstat.jinfo.jmap.jhat.jstack . 1.jps jps:JVM Process Status Too ...
- leetcode合并区间
合并区间 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: ...
- 服务器返回中文乱码的情况(UTF8编码 -> 转化为 SYSTEM_LOCALE 编码)
服务器乱码 转换使用如下方法 入惨{“msg”} -> utf8编码 -> 转化为 SYSTEM_LOCALE 编码 -> 接受转换后的参数 "sEncoding" ...
- 最小生成树(II)与Kruskal算法
为防止网页加载过慢,故分两章.上接https://www.cnblogs.com/Uninstalllingyi/p/10479470.html Kruskal算法——将森林合并成树 玩过瘟疫公司吗… ...
- 本周PSP图
本周共写博文5篇,共计4800字,知识点:知道了博客应当如何写,接触了博客园,阅读了构建之法 内容 开始时间 结束时间 中断时间 共计时间 9月8日博文 22:00 22:55 10min聊天 45m ...
- java报错:Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE
Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE at org.apache.http.conn.ss ...