P4173-残缺的字符串【FFT】
正题
题目链接:https://www.luogu.com.cn/problem/P4173
题目大意
给出两个字符串\(S,T\),其中包含小写字母和一些\(?\),\(?\)可以匹配任何字符。
求有多少个\(p\)使得\(T_{0\sim |t|-1}=S_{p\sim p+|t|-1}\)
解题思路
如果不考虑\(?\),我们可以用做差法来匹配两个字符,构造匹配函数
\]
这样若\(f(x)=0\)证明它们在位置\(x\)处匹配。
但是现在有\(?\),也就是要跳过有\(?\)的位置,定义\(?\)的值为\(0\),然后改一下匹配函数
\]
展开二次项
\]
把\(T\)反过来就是\(\sum_{i=0}^{m}T_{m-i-1}^3S_{x+i}-2T_{m-i-1}^2S_{x+i}^2+T_{m-i-1}S_{x+i}^3\)
然后有三个式子卷积之后加起来就好了。
常数极大,开\(\text{-O2}\)才能过。时间复杂度\(O(n\log n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define int long long
using namespace std;
const int N=1e6+2e5;
const double Pi=acos(-1);
struct complex{
double x,y;
complex(double xx=0,double yy=0)
{x=xx;y=yy;return;}
};
complex operator+(complex a,complex b)
{return complex(a.x+b.x,a.y+b.y);}
complex operator-(complex a,complex b)
{return complex(a.x-b.x,a.y-b.y);}
complex operator*(complex a,complex b)
{return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
struct poly{
complex a[N];
}F[3],G[3];
int n,m,r[N],k;
char s[N],t[N];
queue<int> q;
void FFT(complex *f,int op,int n){
for(int i=0;i<n;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(int p=2;p<=n;p<<=1){
int len=p>>1;
complex tmp(cos(Pi/len),sin(Pi/len)*op);
for(int k=0;k<n;k+=p){
complex buf(1,0);
for(int i=k;i<k+len;i++){
complex tt=buf*f[i+len];
f[i+len]=f[i]-tt;
f[i]=f[i]+tt;
buf=buf*tmp;
}
}
}
if(op==-1)
for(int i=0;i<n;i++)
f[i].x/=(double)n;
return;
}
void mul(poly &a,poly &b){
FFT(a.a,1,k);FFT(b.a,1,k);
for(int i=0;i<k;i++)
a.a[i]=a.a[i]*b.a[i];
FFT(a.a,-1,k);
return;
}
signed main()
{
scanf("%d%d",&m,&n);
scanf("%s",t);scanf("%s",s);
for(int i=0;i<n;i++){
char c=s[i];int z=s[i]-'a'+1;
if(c=='*')z=0;
F[0].a[i]=complex(z*z*z,0);
F[1].a[i]=complex(z*z,0);
F[2].a[i]=complex(z,0);
}
for(int i=0;i<m;i++){
char c=t[m-i-1];int z=c-'a'+1;
if(c=='*')z=0;
G[0].a[i]=complex(z,0);
G[1].a[i]=complex(z*z,0);
G[2].a[i]=complex(z*z*z,0);
}
k=1;for(k=1;k<=2*n;)k<<=1;
for(int i=0;i<k;i++)
r[i]=(r[i>>1]>>1)|((i&1)?(k>>1):0);
mul(F[0],G[0]);mul(F[1],G[1]);mul(F[2],G[2]);
for(int i=0;i<k;i++)
F[0].a[i].x=F[0].a[i].x-2.0*F[1].a[i].x+F[2].a[i].x;
k=0;
for(int i=0;i<=n-m;i++)
if(fabs(F[0].a[i+m-1].x)<0.5)
k++,q.push(i);
printf("%d\n",k);
while(!q.empty())
printf("%d ",q.front()+1),q.pop();
return 0;
}
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类的字符串神仙算法在这里没法用了. 那咋搞啊(或者说这题和数学有半毛钱 ...
- P4173 残缺的字符串(FFT)
[Luogu4173] 题解 \(1.\)定义匹配函数 \(2.\)定义完全匹配函数 \(3.\)快速计算每一位的完全匹配函数值 #include<cstdio> #include< ...
随机推荐
- git 的指定参考教程
https://www.runoob.com/git/git-create-repository.html
- HTTP状态码:3XX
3XX状态码 含义:表明浏览器需要执行某些特殊的处理以正确的处理请求,大部分都需要进行重定向.这类状态码代表需要客户端采取进一步的操作才能完成请求.通常,这些状态码用来重定向,后续的请求地址(重定向目 ...
- spring 》Cglib赋值
第一个:字节码文件时带有ENHANCERBYCGLIB,FastClassByCGLIB组成的文件名 第二个:字节码文件时带有ENHANCERBYCGLIB 第三个:字节码文件时带有FastClass ...
- asp获取当前页面url
<%Function GetLocationURL() Dim Url Dim ServerPort,ServerName,ScriptName,QueryString ServerName = ...
- 面试必备:排序算法汇总(c++实现)
排序算法主要考点: 7种排序 冒泡排序.选择排序.插入排序.shell排序.堆排序.快速排序.归并排序 以上排序算法是面试官经常会问到的算法,至于其他排序比如基数排序等等,这里不列举. 以下算法通过c ...
- openresty(nginx) 配置 http与https使用同一个端口,禁止 IP 直接访问
准备好工作目录 mkdir work cd work mkdir conf logs 准备好 conf/nginx.conf 配置文件, 把 your.domain 换成你自己的域名 user abc ...
- Mybatis-Plus - 条件构造器 QueryWrapper 的使用
目录 前言 查询示例 基础代码 QueryWrapper 的基本使用 QueryWrapper 的lambada写法 LambadaQueryWrapper 的使用 LambdaQueryChainW ...
- 利用job提升马哈鱼数据血缘分析效率
利用job提升马哈鱼数据血缘分析效率 一.Job基本知识 前面文章中已介绍马哈鱼的基本功能,其中一个是job,job其实是一个任务集合处理的概念,就是让用户通过job,可以一次递交所有需要处理的 SQ ...
- VUE006. 前端跨域代理服务器ProxyTable概述与配置
概述 使用 vue-cli 工具生成一个 vue 项目: vue init webpack my-project-vue 在生成的项目结构里,会有一个 index.js 文件.在这个文件里 ...
- python基础--网站推荐
Python教程 - 廖雪峰的官方网站 Python 基础教程 | 菜鸟教程 随笔分类 - 机器学习