题面

传送门:洛咕


Solution

这题我写得脑壳疼,我好菜啊

好吧,我们来说正题。

这题.....emmmmmmm

显然KMP类的字符串神仙算法在这里没法用了。

那咋搞啊(或者说这题和数学有半毛钱关系啊)

我们考虑把两个字符相同强行变为一个数学关系,怎么搞呢?

考虑这题是带通配符的,我们可以这样设:

\(C(x,y)=(A[x]-B[y])^2*A[x]*B[y]\)

因此,我们可以看出两个字符一样当且仅当\(C(x,y)=0\)

因此,我们再设一个函数\(P(x)\)表示\(B\)串以第\(x\)项为结尾的长度为\(m\)的子串是否与\(A\)串匹配,显然有:

\(P(x)=\sum_{i=0}^{m-1}C(i,x-m+i+1)\)

\(P(x)=\sum_{i=0}^{m-1}(A[i]-B[x-m+i+1])^2*A[i]*B[x-m+i+1]\)

后面那个式子写的太蛋疼了,我们把\(x-m+i+1\)设为\(j\)吧。

\(P(x)=\sum_{i=0}^{m-1}(A[i]-B[j])^2*A[i]*B[j]\)

大力展开得:

\(P(x)=\sum_{i=0}^{m-1}A[i]^3B[j]-2A[i]^2B[j]^2+A[i]B[j]^3\)

然后.....我们试着把\(\sum\)展开?

\(P(x)=\sum_{i=0}^{m-1}A[i]^3B[j]-\sum_{i=0}^{m-1}2A[i]^2B[j]^2+\sum_{i=0}^{m-1}A[i]B[j]^3\)

还是没法算啊......

诶,等下,如果我们把\(A\)串反转为\(A'\),肯定有\(A[i]=A'[m-i-1]\)

然后这个\((m-i-1)+(j)\)......不就是等于\(x\)嘛。

所以说我们马上就有:

\(P(x)=\sum_{i+j=x}A[i]^3B[j]-\sum_{i+j=x}2A[i]^2B[j]^2+\sum_{i+j=x}A[i]B[j]^3\)

哦豁,卷积,搞定~

时间复杂度\(O(nlogn)\)

搞定个鬼,这题要做7次FFT,常数爆大,我卡不进去



还请各位dalao赐教。


Code

#include<iostream>
#include<cstdio>
#include<complex>
#include<cmath>
#include<algorithm>
using namespace std;
const int M=300000+100;
const int N=M*4;
const double PI=acos(-1);
const double eps=1e-1;
typedef complex <double> cp;
cp omega(int K,int n)
{
return cp(cos(2*PI*K/n),sin(2*PI*K/n));
}
inline void FFT(cp a[],int n,bool type)
{
static int tmp[N],num=n-1,len;
while(num!=0) num/=2,len++;
for(int i=0,j;i<=n;i++)
{
for(j=0,num=i;j<len;j++)
tmp[j]=num%2,num/=2;
reverse(tmp,tmp+len);
for(j=0,num=0;j<len;j++)
num+=tmp[j]*(1<<j);
if(i<num) swap(a[i],a[num]);
}
for(int l=2;l<=n;l*=2)
{
int m=l/2;
cp x0=omega(1,l);
if(type==true) x0=conj(x0);
for(int i=0;i<n;i+=l)
{
cp x(1,0);
for(int j=0;j<m;j++,x*=x0)
{
cp temp=x*a[i+j+m];
a[i+j+m]=a[i+j]-temp;
a[i+j]=a[i+j]+temp;
}
}
}
}
char A[N],B[N];
int m,n,t=1;
cp S1[N],S2[N],S3[N],B1[N],B2[N],B3[N];
bool OK[N];
int main()
{
scanf("%d%d%s%s",&m,&n,A,B); while(t<=(n+m)) t*=2;
reverse(A,A+m);
for(int i=0;i<t;i++)
A[i]=(A[i]=='*' or A[i]<'a' or A[i]>'z'?0:A[i]-'a'+1),
B[i]=(B[i]=='*' or B[i]<'a' or B[i]>'z'?0:B[i]-'a'+1);
for(int i=0;i<t;i++)
S1[i]=A[i],S2[i]=A[i]*A[i],S3[i]=A[i]*A[i]*A[i];
for(int i=0;i<t;i++)
B1[i]=B[i],B2[i]=B[i]*B[i],B3[i]=B[i]*B[i]*B[i];
FFT(S1,t,false);
FFT(S2,t,false);
FFT(S3,t,false);
FFT(B1,t,false);
FFT(B2,t,false);
FFT(B3,t,false); for(int i=0;i<t;i++)
S3[i]*=B1[i];
for(int i=0;i<t;i++)
S1[i]*=B3[i];
for(int i=0;i<t;i++)
S2[i]*=B2[i];
for(int i=0;i<t;i++)
S3[i]+=S1[i]-2.0*S2[i];
FFT(S3,t,true);
int cnt=0;
for(int i=m-1;i<n;i++)
if(fabs(S3[i].real()/t)<eps)
OK[i]=true,cnt++; printf("%d\n",cnt);
for(int i=m-1;i<n;i++)
if(OK[i]==true)
printf("%d ",i-m+1+1);
return 0;
}

[Luogu P4173]残缺的字符串 ( 数论 FFT)的更多相关文章

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

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

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

    传送门 话说为什么字符串会和卷积扯上关系呢……到底得脑洞大到什么程度才能想到这种东西啊……大佬太珂怕了…… 因为通配符的关系,自动机已经废了 那么换种方式考虑,如果两个字符串每一位对应的编码都相等,那 ...

  3. luogu P4173 残缺的字符串

    传送门 两种做法,一种是依次考虑每种字符,然后如果某个位置是该字符或者是\(*\)对应的值就是1,否则是0,然后把第一个串倒过来,fft卷积起来,最后看对应位置的值是否为m 然而上面那个做法在字符集大 ...

  4. P4173 残缺的字符串(FFT)

    [Luogu4173] 题解 \(1.\)定义匹配函数 \(2.\)定义完全匹配函数 \(3.\)快速计算每一位的完全匹配函数值 #include<cstdio> #include< ...

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

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

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

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

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

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

  8. P4173 残缺的字符串 fft

    题意:给你两个字符串,问你第一个在第二个中出现过多少次,并输出位置,匹配时是模糊匹配*可和任意一个字符匹配 题解:fft加速字符串匹配; 假设上面的串是s,s长度为m,下面的串是p,p长度为n,先考虑 ...

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

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

随机推荐

  1. (转载)浏览器 user-agent 字符串的故事

    本文转载自:http://www.cnblogs.com/ifantastic/p/3481231.html. 如有侵权,请联系处理!   你是否好奇标识浏览器身份的User-Agent,为什么每个浏 ...

  2. Anaconda安装Pytorch(通过本地安装包)

    前提:你已经事先安装好了Anaconda 在线安装pytorch总是出现这样那样的问题,所以我选择先去清华镜像下载好与python版本对应的pytorch和torchvision文件,然后本地安装 清 ...

  3. IDM下载度盘文件

    百度网盘是百度公司推出的一款个人云服务产品.百度网盘官方版操作简单,我们打开后就可以使用该软件来上传.下载文件等.不仅如此百度网盘软件还可以批量上传文件.支持断点传续等功能,重要的是上传的文件不会占用 ...

  4. Python3基础——函数

    ython 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...

  5. Jmeter之『JSR223脚本』

    Json处理(通过JS) 对于Json字符串,需要使用单引号『''』(因为Json中已存在双引号) // String转为Object var jsonObj = JSON.parse('${data ...

  6. 微信小程序中使用 npm包管理 (保姆式教程)

    打开自己的微信小程序项目,在勾选这个选项 然后在第一次应该是失败的提示"没有找到可以构建的npm包". 在 小程序的根目录下比如我的项目如图: 右击鼠标在终端中打开. 然后输入:n ...

  7. Struts2 学习记录-第一天

    Struts2 -01 struts2框架认识 struts2框架是web层框架.struts2框架=webwork+strut1框架发展过来的.struts2框架设计主要用到技术:通过过滤器进行请求 ...

  8. 多测师讲解python _练习题003_高级讲师肖sir

    python 003作业题:# 1.分别打印100以内的所有偶数和奇数并存入不同的列表当中# 2.请写一段Python代码实现删除一个list = [1, 3, 6, 9, 1, 8]# 里面的重复元 ...

  9. 深入了解Redis(7)-缓存穿透,雪崩,击穿

    redis作为一个内存数据库,在生产环境中使用会遇到许多问题,特别是像电商系统用来存储热点数据,容易出现缓存穿透,雪崩,击穿等问题.所以实际运用中需要做好前期处理工作. 一.缓存雪崩 1.概念 缓存雪 ...

  10. 分布式系统中的CAP、ACID、BASE概念

    目录 CAP ACID BASE CAP 分布式系统中,这三个特性只能满足其中两个. 一致性(Consistency):分布式中一致性又分强一致性和弱一致性,强一致性主浊任何时刻任何节点看到的数据都是 ...