[BZOJ4259]残缺的字符串
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ4259]残缺的字符串
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Description:
給定兩個帶通配符的串,求可能出現(xiàn)幾次匹配,以及這些匹配位置
Hint:
\(n \le 3*10^5\)
Solution:
定義匹配函數(shù) \(P(x)=\sum_{i=x}^{x+m}(S1[i]-S2[i])^2*S1[i]*S2[i]?\)
展開的式子太長,有時間再放
大概是一堆字符串卷積
翻轉(zhuǎn)后FFT即可
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define ls p<<1 #define rs p<<1|1 using namespace std; typedef long long ll; const int mxn=2e6+5; const double PI=acos(-1); int n,m,l,tot,lim=1,a[mxn],b[mxn],r[mxn],q[mxn]; ll s[mxn]; char s1[mxn],s2[mxn]; inline int read() {char c=getchar(); int x=0,f=1;while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}return x*f; } inline int chkmax(register int &x,register int y) {if(x<y) x=y;} inline int chkmin(register int &x,register int y) {if(x>y) x=y;}struct ed {int to,nxt; }t[mxn<<1];struct cp {double x,y;cp (double xx=0,double yy=0) {x=xx;y=yy;}friend cp operator + (cp a,cp b) {return cp(a.x+b.x,a.y+b.y);}friend cp operator - (cp a,cp b) {return cp(a.x-b.x,a.y-b.y);}friend cp operator * (cp a,cp b) {return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);} }A[mxn],B[mxn],C[mxn];void FFT(cp *p,register int opt) {for(register int i=0;i<lim;++i) if(i<r[i]) swap(p[i],p[r[i]]);for(register int mid=1;mid<lim;mid<<=1) {cp wn=cp(cos(PI/mid),opt*sin(PI/mid));for(register int len=mid<<1,j=0;j<lim;j+=len) {cp w=cp(1,0);for(register int k=0;k<mid;++k,w=w*wn) {cp x=p[j+k],y=w*p[j+mid+k];p[j+k]=x+y; p[j+mid+k]=x-y;}}} }int main() {scanf("%d%d%s%s",&m,&n,s1,s2);for(register int i=0,j=m-1;i<j;++i,--j) swap(s1[i],s1[j]);for(register int i=0;i<m;++i) if(s1[i]!='*') a[i]=s1[i]-'a'+1;for(register int i=0;i<n;++i) if(s2[i]!='*') b[i]=s2[i]-'a'+1;while(lim<=n+m) ++l,lim<<=1;for(register int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));for(register int i=0;i<=lim;++i) A[i]=cp(a[i]*a[i]*a[i],0),B[i]=cp(b[i],0);FFT(A,1); FFT(B,1); for(register int i=0;i<=lim;++i) C[i]=A[i]*B[i];FFT(C,-1);for(register int i=0;i<=lim;++i) s[i]+=(ll)(C[i].x/lim+0.5);for(register int i=0;i<=lim;++i) A[i]=cp(a[i],0),B[i]=cp(b[i]*b[i]*b[i],0);FFT(A,1); FFT(B,1);for(register int i=0;i<=lim;++i) C[i]=A[i]*B[i];FFT(C,-1);for(register int i=0;i<=lim;++i) s[i]+=(ll)(C[i].x/lim+0.5);for(register int i=0;i<=lim;++i)A[i]=cp(a[i]*a[i],0),B[i]=cp(b[i]*b[i],0);FFT(A,1); FFT(B,1); for(register int i=0;i<=lim;++i) C[i]=A[i]*B[i];FFT(C,-1);for(register int i=0;i<=lim;++i) s[i]-=2*(ll)(C[i].x/lim+0.5);for(register int i=m-1;i<n;++i) if(s[i]==0) q[++tot]=i-m+2;printf("%d\n",tot);for(register int i=1;i<=tot;++i) printf("%d ",q[i]);return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/list1/p/10504685.html
總結(jié)
以上是生活随笔為你收集整理的[BZOJ4259]残缺的字符串的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mongodb 基础 查询表达式
- 下一篇: chmod 755 是李鬼(转)