【xsy1154】 DNA配对 FFT
题目大意:给你一个字符串s和字符串w,字符集为A,T,C,G,你要在字符串s中选出一个与w长度相同的子串,使得这两个串的差异度最小。
两个字符c1,c2的差异度为给定的c[c1][c2]。
字符串长度≤2∗105。
FFT套路题。
我们将串w翻转。
设p[i]为s中子串s[i−|w|+1.......i]与w的差异度。
显然p[i]=∑ij=0c[s[j]][w[i−j]]。(此处的w是翻转后的)
显然的卷积形式。
五次FFT即可。
1 #include<bits/stdc++.h> 2 #define M (1<<19) 3 #define PI acos(-1) 4 #define INF 19890604 5 using namespace std; 6 7 struct cp{ 8 double i,r; cp(){i=r=0;} 9 cp(double rr,double ii){i=ii;r=rr;} 10 friend cp operator +(cp a,cp b){return cp(a.r+b.r,a.i+b.i);} 11 friend cp operator -(cp a,cp b){return cp(a.r-b.r,a.i-b.i);} 12 friend cp operator *(cp a,cp b){return cp(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);} 13 friend cp operator /(cp a,double b){return cp(a.r/b,a.i/b);} 14 int num(){return (int)(i+0.499)/2;} 15 }a[M],b[M],c[M],d[M],ans[M]; 16 17 void change(cp a[],int len){ 18 for(int i=0,j=0;i<len-1;i++){ 19 if(i<j) swap(a[i],a[j]); 20 int k=len>>1; 21 while(j>=k) j-=k,k>>=1; 22 j+=k; 23 } 24 } 25 void FFT(cp a[],int len,int on){ 26 change(a,len); 27 for(int h=2;h<=len;h<<=1){ 28 cp wn=cp(cos(2*on*PI/h),sin(2*on*PI/h)); 29 for(int j=0;j<len;j+=h){ 30 cp w=cp(1,0); 31 for(int k=j;k<(j+(h>>1));k++){ 32 cp u=a[k],t=w*a[k+(h>>1)]; 33 a[k]=u+t; a[k+(h>>1)]=u-t; 34 w=w*wn; 35 } 36 } 37 } 38 if(on==-1) for(int i=0;i<len;i++) a[i]=a[i]/len; 39 } 40 41 int D[4][4]={0}; 42 int get(char c){ 43 if(c=='A') return 0; 44 if(c=='T') return 1; 45 if(c=='C') return 2; 46 if(c=='G') return 3; 47 } 48 49 char s[M]={0},w[M]={0}; 50 int n,m; 51 int main(){ 52 scanf("%s%s",s,w); n=strlen(s); m=strlen(w); 53 for(int i=0;i<16;i++) scanf("%d",D[0]+i); 54 for(int i=0;i<n;i++) s[i]=get(s[i]); 55 for(int i=0;i<m;i++) w[i]=get(w[i]); 56 reverse(w,w+m); 57 for(int i=0;i<n;i++){ 58 if(s[i]==0) a[i].i=1; 59 if(s[i]==1) b[i].i=1; 60 if(s[i]==2) c[i].i=1; 61 if(s[i]==3) d[i].i=1; 62 } 63 for(int i=0;i<m;i++){ 64 a[i].r=D[0][w[i]]; 65 b[i].r=D[1][w[i]]; 66 c[i].r=D[2][w[i]]; 67 d[i].r=D[3][w[i]]; 68 } 69 int len=1; while(len<n+m) len<<=1; 70 FFT(a,len,1); FFT(b,len,1); FFT(c,len,1); FFT(d,len,1); 71 for(int i=0;i<len;i++){ 72 ans[i]=a[i]*a[i]+b[i]*b[i]+c[i]*c[i]+d[i]*d[i]; 73 } 74 FFT(ans,len,-1); 75 int minn=INF; 76 for(int i=m-1;i<n;i++) 77 minn=min(minn,ans[i].num()); 78 cout<<minn<<endl; 79 }
分类:
FFT
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!