[BZOJ4259]残缺的字符串(FFT)
来源:互联网 发布:淘宝链接转化微信 编辑:程序博客网 时间:2024/04/29 10:01
题目描述
传送门
题目大意:给出一个模板串和一个母串,问模板串在母串中出现过几次。带通配符。
题解
这道题和两个串那道题是差不多的。。
令F(i)表示将模板串的最后一个怼到母串的第i个是否能匹配,0表示能匹配,非0表示不能匹配。然后设两个函数f(i)=(t(i)=‘ * ’)?0:t(i),g(i)=(s(i)=‘ * ’)?0:s(i)
将模板串倒置了之后显然
这样做三遍FFT求出F(i)就行了
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 2000005const double pi=acos(-1.0);struct complex{ double x,y; complex(double X=0,double Y=0) { x=X,y=Y; }}a[N],b[N];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);}int S,T,n,m,L,R[N],ans[N];long long F[N];char s[N],t[N];double f[N],g[N];void FFT(complex a[N],int opt){ for (int i=0;i<n;++i) if (i<R[i]) swap(a[i],a[R[i]]); for (int k=1;k<n;k<<=1) { complex wn=complex(cos(pi/k),opt*sin(pi/k)); for (int i=0;i<n;i+=(k<<1)) { complex w=complex(1,0); for (int j=0;j<k;++j,w=w*wn) { complex x=a[i+j],y=w*a[i+j+k]; a[i+j]=x+y,a[i+j+k]=x-y; } } }}void calc(int opt){ FFT(a,1);FFT(b,1); for (int i=0;i<=n;++i) a[i]=a[i]*b[i]; FFT(a,-1); for (int i=0;i<T;++i) F[i]+=(long long)(a[i].x/n+0.5)*opt;}int main(){ scanf("%d%d",&S,&T); scanf("%s%s",s,t); for (int i=0;i<S/2;++i) swap(s[i],s[S-i-1]); for (int i=0;i<T;++i) f[i]=(t[i]=='*')?0:(t[i]-'a'+1.0); for (int i=0;i<S;++i) g[i]=(s[i]=='*')?0:(s[i]-'a'+1.0); m=S+T-2; for (n=1;n<=m;n<<=1) ++L; for (int i=0;i<n;++i) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1)); for (int i=0;i<=n;++i) a[i]=complex(0,0),b[i]=complex(0,0); for (int i=0;i<T;++i) a[i].x=f[i]*f[i]*f[i]; for (int i=0;i<S;++i) b[i].x=g[i]; calc(1); for (int i=0;i<=n;++i) a[i]=complex(0,0),b[i]=complex(0,0); for (int i=0;i<T;++i) a[i].x=f[i]*f[i]; for (int i=0;i<S;++i) b[i].x=g[i]*g[i]; calc(-2); for (int i=0;i<=n;++i) a[i]=complex(0,0),b[i]=complex(0,0); for (int i=0;i<T;++i) a[i].x=f[i]; for (int i=0;i<S;++i) b[i].x=g[i]*g[i]*g[i]; calc(1); for (int i=S-1;i<T;++i) if (!F[i]) ans[++ans[0]]=i-S+2; printf("%d\n",ans[0]); for (int i=1;i<=ans[0];++i) printf("%d%c",ans[i]," \n"[i==ans[0]]);}
0 0
- [BZOJ4259] 残缺的字符串 (FFT)
- [BZOJ4259]残缺的字符串(FFT)
- [BZOJ4259][FFT]残缺的字符串
- bzoj4259残缺的字符串FFT解题报告
- bzoj4259: 残缺的字符串
- bzoj4259: 残缺的字符串
- [BZOJ4259]残缺的字符串
- bzoj 4259: 残缺的字符串 (FFT)
- bzoj4259 -- FFT
- BZOJ 4259 残缺的字符串
- bzoj 4259 残缺的字符串
- “残缺”程序员的屌丝录(一)
- “残缺”程序员的屌丝录(二)
- “残缺”程序员的屌丝录(三)
- “残缺”程序员的屌丝录(四)
- “残缺”程序员的屌丝录(五)
- CSUOJ 1511 残缺的棋盘(BFS)
- 残缺的棋盘(dijkstra算法)
- imageView图片动态改变背景图
- 学习Linux系统中命令的简单方法
- Java设计模式六大原则之场景应用分析
- js逻辑操作符(!,&&,||)与运算符优先级
- spring boot 集成swagger
- [BZOJ4259]残缺的字符串(FFT)
- HAUT 1261 地狱飞龙(数值积分)(河南工业大学2017校赛)
- 从零写一个GAN
- 安卓 每隔一段时间执行一次操作
- 设置短信验证码动态计时器
- #ifndef/#define/#endif使用详解
- tableView 自定义分隔线
- spark部署模式解析
- SQL Server存储过程分页