codeforces 528D. Fuzzy Search (FFT优化DP)
来源:互联网 发布:linux怎么读音是什么 编辑:程序博客网 时间:2024/06/13 22:27
题目描述
传送门
题目大意:给出一个母串和一个模板串,求模板串在母串中的匹配次数。
匹配时,如果用s[i]匹配t[j],那么只要s[i-k]-s[i+k]中有字母与t[j]相同即可算作匹配成功。其中s[i]表示母串的第i位,t[j]表示模板串的第j位。
题解
如果数据范围小的话,这题就是一个DP
f[i][j]=f[i-1][j-1]&mp[i][t[j]]表示母串的第i位匹配到模板串的第j位是否可以匹配上。
其中
我们要用
我们计算的时候将所有的字符分开考虑
对于母串来说,如果第
对于模板串来说,如果第
令
只有
上面的式子可以用
然后我们统计每一位所有字符的
代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define N 500003 #define pi acos(-1) using namespace std; struct data{ double x,y; data(double X=0,double Y=0) { x=X,y=Y; } }a[N*5],b[N*5]; data operator +(data a,data b){ return data(a.x+b.x,a.y+b.y); } data operator -(data a,data b){ return data(a.x-b.x,a.y-b.y); } data operator *(data a,data b){ return data(a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y); } int n,m,k,n1,col[N],cl[N],mp[N][5],cost[N]; char s[N]; int calc(char c) { if (c=='A') return 1; if (c=='G') return 2; if (c=='C') return 3; if (c=='T') return 4; } void clear(data a[N]){ for (int i=1;i<=n1;i++) a[i].x=0,a[i].y=0;}void fft(data x[N],int n,int opt) { if (n==1) return; data l[n>>1],r[n>>1]; for (int i=0;i<n;i+=2) l[i>>1]=x[i],r[i>>1]=x[i+1]; fft(l,n>>1,opt); fft(r,n>>1,opt); data wn=data(cos(2*pi/n),sin(2*opt*pi/n)); data w=data(1,0),t; for (int i=0;i<n>>1;i++,w=wn*w) t=w*r[i],x[i]=l[i]+t,x[i+(n>>1)]=l[i]-t; } int main() { freopen("a.in","r",stdin); scanf("%d%d%d",&n,&m,&k); scanf("%s",s); n--; for (int i=0;i<=n;i++) col[i]=calc(s[i]); scanf("%s",s); m--; for (int i=0;i<=m;i++) cl[i]=calc(s[m-i]); for (int i=1;i<=4;i++) { int nxt=-1; for (int j=0;j<=n;j++){ if (nxt!=-1&&nxt>=j-k||col[j]==i) mp[j][i]=1; if (col[j]==i) nxt=j; } nxt=-1; for (int j=n;j>=0;j--) { if (nxt!=-1&&nxt<=j+k||col[j]==i) mp[j][i]=1; if (col[j]==i) nxt=j; } } int tot=n+m; for (n1=1;n1<=tot;n1<<=1); for (int i=1;i<=4;i++) { clear(b); clear(a); for (int j=0;j<=n;j++) if (mp[j][i]) a[j].x=1; else a[j].x=0; for (int j=0;j<=m;j++) if (cl[j]==i) b[j].x=1; else b[j].x=0; fft(a,n1,1); fft(b,n1,1); for (int j=0;j<=n1;j++) a[j]=a[j]*b[j]; fft(a,n1,-1); for (int j=0;j<=n;j++) cost[j]+=(int)(a[j].x/n1+0.5); } int ans=0; for (int i=0;i<=n;i++) if (cost[i]==m+1) ans++; printf("%d\n",ans); }
0 0
- codeforces 528D. Fuzzy Search (FFT优化DP)
- CodeForces 528 D.Fuzzy Search(FFT)
- 【codeforces】528D. Fuzzy Search【FFT】
- codeforces 528D Fuzzy Search FFT
- codeforces 528D Fuzzy Search
- 【FFT】 Codeforces Round #296 (Div. 1) D - Fuzzy Search
- [Codeforces528D]Fuzzy Search(FFT)
- Codeforces Round #296 (Div. 1) D. Fuzzy Search
- [Codeforces 484D] Kindergarten (DP + 树状数组优化)
- CodeForces 10D(DP)
- codeforces 682D(DP)
- Codeforces-Goodbye2016-D(DP)
- codeforces #343 div2 D. Babaei and Birthday Cake(DP+离散化+线段树优化)
- Codeforces 629D Babaei and Birthday Cake(线段树优化dp)
- Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)
- Codeforces 712D Memory and Scores(前缀和优化dp)
- CodeForces 573D Bear and Cavalry(线段树优化dp)
- Codeforces 55D Beautiful numbers 数位dp 数论 优化技巧
- 简单的shell程序
- int * const *, const int * const *, const int **
- 【bzoj3238】差异 后缀自动机
- Python基础教程(2)
- 为什要使用BindService?为了调用服务中的方法
- codeforces 528D. Fuzzy Search (FFT优化DP)
- 453. Minimum Moves to Equal Array Elements
- leetcode总结帖
- c++ 调试问题 集合
- 55. Jump Game
- 【BZOJ 2618】[Cqoi2006]凸多边形 半平面交
- 来电去电自动录音
- 上下移动页面元素的代码
- BZOJ 1087 [SCOI2005] 互不侵犯King