生活随笔
收集整理的這篇文章主要介紹了
LGP4173残缺的字符串
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
-
題解
- 由于有通配符,所以$kmp$失效了;
- 將通配符看成0,其余字符看成互不相同的數字,$A,B$串對應得到$a,b$數組;
- 定義:
- $f(p) = \sum_{i=0}^{m-1} a_{i}b_{p+i} (a_{i} - b_{p+i})^2 $
- 只需要判斷$f(p)$是否為0就可以知道$p$開頭是否可以匹配;
- $f(p) = \sum_{i=0}^{m-1}? ?a_{i}^{3} b_{p+i}? ?-? 2 a_{i}^2 b_{p+i}^2? +?a_{i} b_{p+i}^{3}? $
- 反轉一下$A$串湊成卷積:
- $f(p) = \sum_{i=0}^{m-1} a_{m-1-i}^{3} b_{p+i} - 2 a_{m-1-i}^{2} b_{p+i}^{2} + a_{m-1-i} b_{p+i}^{3}$
- 做三次$DFT$一次$IDFT$求出三個卷積和即可;
- 注意$B$串沒有的位置全是0;
1 // luogu-judger-enable-o2
2 #include<bits/stdc++.h>
3 #define ld double
4 using namespace std;
5 const int N=
1<<
20;
6 const ld pi=acos(-
1);
7 int m,n,len,L,t1[N],t2[N],tot,ans[N],rev[N];
8 char s[N];
9 struct C{
10 ld x,y;
11 C(ld _x=
0,ld _y=
0):x(_x),y(_y){};
12 C
operator +(
const C&A)
const{
return C(x+A.x,y+
A.y);}
13 C
operator -(
const C&A)
const{
return C(x-A.x,y-
A.y);}
14 C
operator *(
const C&A)
const{
return C(x*A.x-y*A.y,x*A.y+y*
A.x);}
15 C
operator /(
const ld&A)
const{
return C(x/A,y/
A);}
16 }a[N],b[N],c[N];
17 void fft(C*a,
int f){
18 for(
int i=
0;i<len;++i)
if(i<
rev[i])swap(a[i],a[rev[i]]);
19 for(
int i=
1;i<len;i<<=
1){
20 C wn=C(cos(pi/i),f*sin(pi/
i));
21 for(
int j=
0;j<len;j+=i<<
1){
22 C w=C(
1,
0);
23 for(
int k=
0;k<i;++k,w=w*
wn){
24 C x=a[j+k],y=w*a[i+j+
k];
25 a[j+k]=x+y,a[i+j+k]=x-
y;
26 }
27 }
28 }
29 if(!~f)
for(
int i=
0;i<len;++i)a[i]=a[i]/
len;
30 }
31 int main(){
32 // freopen("P4173.in","r",stdin);
33 // freopen("P4173.out","w",stdout);
34 scanf(
"%d%d",&m,&
n);
35 scanf(
"%s",s);
36 for(
int i=
0;i<m;++i)t1[i]=s[m-i-
1]==
'*'?
0:s[m-i-
1]-
'a'+
1;
37 scanf(
"%s",s);
38 for(
int i=
0;i<n;++i)t2[i]=s[i]==
'*'?
0:s[i]-
'a'+
1;
39 for(len=
1;len<n+m;len<<=
1,L++
);
40 for(
int i=
1;i<len;++i)rev[i]=(rev[i>>
1]>>
1)|((i&
1)<<(L-
1));
41
42 for(
int i=
0;i<len;++i)a[i].x=t1[i]*t1[i]*t1[i],a[i].y=
0;
43 for(
int i=
0;i<len;++i)b[i].x=t2[i],b[i].y=
0;
44 fft(a,
1);fft(b,
1);
45 for(
int i=
0;i<len;++i)c[i]=c[i]+a[i]*
b[i];
46
47 for(
int i=
0;i<len;++i)a[i].x=t1[i]*t1[i],a[i].y=
0;
48 for(
int i=
0;i<len;++i)b[i].x=t2[i]*t2[i],b[i].y=
0;
49 fft(a,
1);fft(b,
1);
50 for(
int i=
0;i<len;++i)c[i]=c[i]-a[i]*b[i]*
2;
51
52 for(
int i=
0;i<len;++i)a[i].x=t1[i],a[i].y=
0;
53 for(
int i=
0;i<len;++i)b[i].x=t2[i]*t2[i]*t2[i],b[i].y=
0;
54 fft(a,
1);fft(b,
1);
55 for(
int i=
0;i<len;++i)c[i]=c[i]+a[i]*
b[i];
56
57 fft(c,-
1);
58 for(
int i=
0;i<=n-m;++
i){
59 int d=floor(c[i+m-
1].x+
0.5);
60 if(!d)ans[++tot]=
i;
61 }
62 printf(
"%d\n",tot);
63 for(
int i=
1;i<=tot;++i)printf(
"%d ",ans[i]+
1);
64 return 0;
65 }
View Code ?
??
轉載于:https://www.cnblogs.com/Paul-Guderian/p/10433335.html
總結
以上是生活随笔為你收集整理的LGP4173残缺的字符串的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。