P4173 残缺的字符串(FFT)
\(1.\)定义匹配函数
\(2.\)定义完全匹配函数
\(3.\)快速计算每一位的完全匹配函数值
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
}
inline char readc(){
register char c=getchar();
while(c==' '||c=='\n'||c=='\t') c=getchar();
return c;
}
const int MAXN=2e6+5;
const double Pi=acos(-1);
struct cmpx{
double x,y;
inline cmpx(){}
inline cmpx(double _x,double _y){x=_x,y=_y;}
inline friend cmpx operator + (cmpx a,cmpx b){return cmpx(a.x+b.x,a.y+b.y);}
inline friend cmpx operator - (cmpx a,cmpx b){return cmpx(a.x-b.x,a.y-b.y);}
inline friend cmpx operator * (cmpx a,cmpx b){return cmpx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
inline friend cmpx operator * (cmpx a,double b){return cmpx(a.x*b,a.y*b);}
}A[MAXN],B[MAXN],C[MAXN];
char s[MAXN],t[MAXN];
int ans[MAXN],a[MAXN],b[MAXN];
int n,m;
namespace F_F_T{
int rev[MAXN],limit,l;
inline void init(int n){
for(limit=1,l=0;limit<=n;limit<<=1) l++;
for(int i=0;i<limit;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
}
inline void FFT(cmpx *A,int type){
for(int i=0;i<limit;i++)
if(i<rev[i]) swap(A[i],A[rev[i]]);
for(int len=1;len<limit;len<<=1){
cmpx Wn=(cmpx){cos(Pi/len),type*sin(Pi/len)};
for(int i=0;i<limit;i+=(len<<1)){
cmpx w=(cmpx){1,0};
for(int j=0;j<len;j++,w=w*Wn){
cmpx x=A[i+j],y=w*A[i+len+j];
A[i+j]=x+y;
A[i+len+j]=x-y;
}
}
}
if(type==-1){
for(int i=0;i<limit;i++) A[i].x/=limit;
}
}
}using namespace F_F_T;
int main(){
n=read(),m=read();
init(n+m-2);
for(int i=n-1;i>=0;i--){
char c=readc();
a[i]=(c!='*')?c-'a'+1:0;
}
for(int i=0;i<m;i++){
char c=readc();
b[i]=(c!='*')?c-'a'+1:0;
}
for(int i=0;i<n;i++) A[i]=cmpx(a[i]*a[i]*a[i],0);
for(int i=0;i<m;i++) B[i]=cmpx(b[i],0);
FFT(A,1);FFT(B,1);
for(int i=0;i<limit;i++) C[i]=A[i]*B[i];
for(int i=0;i<limit;i++) A[i]=B[i]=cmpx(0,0);
for(int i=0;i<n;i++) A[i]=cmpx(a[i],0);
for(int i=0;i<m;i++) B[i]=cmpx(b[i]*b[i]*b[i],0);
FFT(A,1);FFT(B,1);
for(int i=0;i<limit;i++) C[i]=C[i]+A[i]*B[i];
for(int i=0;i<limit;i++) A[i]=B[i]=cmpx(0,0);
for(int i=0;i<n;i++) A[i]=cmpx(a[i]*a[i],0);
for(int i=0;i<m;i++) B[i]=cmpx(b[i]*b[i],0);
FFT(A,1);FFT(B,1);
for(int i=0;i<limit;i++) C[i]=C[i]-A[i]*B[i]*2.0;
FFT(C,-1);
for(int i=n-1;i<m;i++){
if(fabs(C[i].x)<0.5) ans[++ans[0]]=i-n+2;
//printf("%.3lf\n",C[i].x);
}
printf("%d\n",ans[0]);
for(int i=1;i<=ans[0];i++)
printf("%d ",ans[i]);
}
P4173 残缺的字符串(FFT)的更多相关文章
- Luogu P4173 残缺的字符串-FFT在字符串匹配中的应用
P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C ...
- P4173 残缺的字符串(FFT字符串匹配)
P4173 残缺的字符串(FFT字符串匹配) P4173 解题思路: 经典套路将模式串翻转,将*设为0,设以目标串的x位置匹配结束的匹配函数为\(P(x)=\sum^{m-1}_{i=0}[A(m-1 ...
- 洛谷 P4173 残缺的字符串 (FFT)
题目链接:P4173 残缺的字符串 题意 给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置. 思路 FFT 带有通配符的字符串匹配问题. 设模式串为 ...
- P4173 残缺的字符串 fft
题意:给你两个字符串,问你第一个在第二个中出现过多少次,并输出位置,匹配时是模糊匹配*可和任意一个字符匹配 题解:fft加速字符串匹配; 假设上面的串是s,s长度为m,下面的串是p,p长度为n,先考虑 ...
- luoguP4173 残缺的字符串 FFT
luoguP4173 残缺的字符串 FFT 链接 luogu 思路 和昨天做的题几乎一样. 匹配等价于(其实我更喜欢fft从0开始) \(\sum\limits_{i=0}^{m-1}(S[i+j]- ...
- BZOJ 4259: 残缺的字符串 [FFT]
4259: 残缺的字符串 题意:s,t,星号任意字符,匹配方案数 和上题一样 多乘上一个\(a_{j+i}\)就行了 #include <iostream> #include <cs ...
- 【BZOJ4259】残缺的字符串 FFT
[BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时, ...
- 洛谷P4173 残缺的字符串(FFT)
传送门 话说为什么字符串会和卷积扯上关系呢……到底得脑洞大到什么程度才能想到这种东西啊……大佬太珂怕了…… 因为通配符的关系,自动机已经废了 那么换种方式考虑,如果两个字符串每一位对应的编码都相等,那 ...
- [Luogu P4173]残缺的字符串 ( 数论 FFT)
题面 传送门:洛咕 Solution 这题我写得脑壳疼,我好菜啊 好吧,我们来说正题. 这题.....emmmmmmm 显然KMP类的字符串神仙算法在这里没法用了. 那咋搞啊(或者说这题和数学有半毛钱 ...
随机推荐
- 0016_练习题d2
__author__ = 'qq593' #!/usr/bin/env python #-*- coding:utf-8 -*- #元素分类,有如下值集合[11,22,33,44,55,66,77,8 ...
- Ajax笔记(一)
Ajax三步骤: Asynchronous Javascript And XML 1.运用HTML和CSS实现页面,表达信息: 2.运用XMLHttpRequest和web服务器进行数据的异步交换: ...
- TextView中ellipsize属性
TextView中可以设置一个ellipsize属性,作用是当文字长度超过textview宽度时的显示方式: 例如,"encyclopedia"显示, 只是举例,以实际显示为准:) ...
- HDU 4348(主席树 标记永久化)
题面一看就是裸的数据结构题,而且一看就知道是主席树... 一共四种操作:1:把区间[l, r]的数都加上d,并且更新时间.2:查询当前时间的区间和.3:查询历史时间的区间和.4:时光倒流到某个时间. ...
- CURD 操作 [2]
一.数据读取 在之前的课程中,我们已经大量使用了数据读取的功能,比如 select()方法.结合各种连贯方法可以实现数据读取的不同要求,支持连贯的方法有: 1.where,查询或更新条件:2.tabl ...
- ECMAScript 定义类、对象
使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的类和对象. ECMAScript 拥有很多创建对象或类的方法. 工厂方式 原始的方式 因为对象的属性可以在对象创建后动 ...
- SpringMVC_04 拦截器 【拦截器的编程步骤】【session复习?】
待更新... 2017年5月13日22:45:31 1 什么是拦截器 spring提供的一个特殊组件,前端控制器 DispacherServlet 在收到请求之后,会先调用拦截器,再调用处理器(Co ...
- Java-马士兵设计模式学习笔记-工厂模式-单例及多例
一.单例的作用是用于控制类的生成方式,而不让外部类任意new对象 1.Car.java import java.util.ArrayList; import java.util.List; publi ...
- input与字符串格式化
# Auther: Aaron Fan #字符转格式化: name = input("Enter your name: ")age = int(input("Enter ...
- scau 2015寒假训练
并不是很正规的.每个人自愿参与自愿退出,马哥找题(马哥超nice么么哒). 放假第一周与放假结束前一周 2015-01-26 http://acm.hust.edu.cn/vjudge/contest ...