bzoj 4503: 两个串 fft
来源:互联网 发布:二维数组指针定义 编辑:程序博客网 时间:2024/06/06 01:35
没想到这种字符串题居然可以用fft。。。
设有两个串S1,S2,定义S1和S2的距离为:Σ(i=1,n) (s1[i]-s2[i])^2,那么两个串相同当且仅当距离=0。那么现在S2存在通配字符'?',那么;令'?'的值为0,就可以修改一下距离为:Σ(i=1,n) s2[i]*(s1[i]-s2[i])^2。
那么把S2翻转一下就变成卷积的形式了,直接上fft即可。注意可以把多次的点值的结果并在一起最后使用一次插值即可。
AC代码如下:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define pi acos(-1.0)#define N 300005using namespace std;struct cpx{ double r,i; }a[N],b[N],c[N]; int n1,n2,m,f[N],g[N],pos[N];char s1[N],s2[N];cpx operator +(cpx x,cpx y){ x.r+=y.r; x.i+=y.i; return x; }cpx operator -(cpx x,cpx y){ x.r-=y.r; x.i-=y.i; return x; }cpx operator *(cpx x,cpx y){cpx t; t.r=x.r*y.r-x.i*y.i; t.i=x.r*y.i+x.i*y.r; return t;}void dft(cpx *a,int flag){int i,j,k; cpx w,wn,u,v;if (flag>0) for (i=0; i<m; i++) a[i].i=0;for (k=1; k<m; k<<=1){wn.r=cos(pi*flag/k); wn.i=sin(pi*flag/k);for (i=0; i<m; i+=(k<<1)){w.r=1; w.i=0;for (j=i; j<i+k; j++){u=a[j]; v=a[j+k]*w;a[j]=u+v; a[j+k]=u-v; w=w*wn;}}}if (flag<0) for (i=0; i<m; i++) a[i].r/=m;}int main(){scanf("%s%s",s1+1,s2+1); int i,j,k,cnt=0;n1=strlen(s1+1); n2=strlen(s2+1);for (i=1; i<=n1; i++) f[i]=s1[i]-'a'+1;for (i=1; i<=n2; i++) g[n2-i+1]=(s2[i]=='?')?0:s2[i]-'a'+1;m=n1+n2+1;for (i=1; i<m; i<<=1) cnt++; m=i;for (i=0; i<m; i++)for (k=i,j=1; j<=cnt; j++,k>>=1) pos[i]=pos[i]<<1|(k&1);for (i=0; i<m; i++){ a[pos[i]].r=f[i]*f[i]; b[pos[i]].r=g[i]; }dft(a,1); dft(b,1);for (i=0; i<m; i++) c[pos[i]]=a[i]*b[i];for (i=0; i<m; i++){ a[pos[i]].r=1; b[pos[i]].r=g[i]*g[i]*g[i]; }dft(a,1); dft(b,1);for (i=0; i<m; i++) c[pos[i]]=c[pos[i]]+a[i]*b[i];for (i=0; i<m; i++){ a[pos[i]].r=f[i]*2; b[pos[i]].r=g[i]*g[i]; }dft(a,1); dft(b,1);for (i=0; i<m; i++) c[pos[i]]=c[pos[i]]-a[i]*b[i];dft(c,-1); cnt=0;for (i=1; i<=n1-n2+1; i++) if (c[i+n2].r<0.5) f[++cnt]=i;printf("%d\n",cnt);for (i=1; i<=cnt; i++) printf("%d\n",f[i]-1);return 0;}
by lych
2016.4.11
0 0
- bzoj 4503: 两个串 fft
- bzoj 4503: 两个串 fft
- bzoj 4503: 两个串 (FFT+DP)
- BZOJ 4503: 两个串 FFT 通配符匹配
- [BZOJ]4503 两个串:我的第一次FFT尝试
- 4503: 两个串 FFT
- 两个串-----FFT妙用!
- Bzoj4503 两个串 FFT
- 【BZOJ 4503】两个串
- BZOJ 4503 两个串
- BZOJ 4503: 两个串
- bzoj 4503 两个串
- Bzoj4503:两个串:FFT,构造
- [BZOJ4503]两个串(FFT)
- bzoj4503两个串 快速傅里叶变换(FFT)
- 【bzoj 2179】FFT
- BZOJ 2179 [FFT]
- BZOJ 2179 FFT模板
- plsql学习的心得
- lightoj 1198 - Karate Competition 贪心
- VS2013MFC对话框工程学习笔记七 - C++数据类型 - 整形 的简单学习
- private ,this ,static 关键字
- linux命令之ls 、cd
- bzoj 4503: 两个串 fft
- Linux C 入门准备
- SOJ 4467 easyproblem 2【欧拉函数 最大公因数和】
- linux 挂载新硬盘
- 算法_动态规划_石子合并问题
- 内核态下基于动态感染技术的应用程序执行保护(三 获取SSDT)
- ubuntu下文本编辑器VI
- 推荐算法——基于矩阵分解的推荐算法
- npm安装一些包失败,解决方法