給出兩個字串,乙個模式串,乙個匹配串,問匹配串中哪些位置可以匹配上模式串,其中*可以作任意字元。
這個可以轉化為多項式,我們可以把*看作0,其他字母看作各個數字,然後發現如果兩個字串相同,當且僅當∑i=
0n−1
(a[i
]−b[
i])2
∗a[i
]∗b[
i]==
0\sum_^==0
∑i=0n−
1(a
[i]−
b[i]
)2∗a
[i]∗
b[i]
==0成立,因此可以用fft來做。
#include
#define db double
#define pi 3.14159265358979
#define eps 0.5
#define n 2100000
using
namespace std;
int m,n,l,rev[n]
;string str;
struct xs;}
xs operator-(
const xs &u)
const;}
xs operator*(
const xs &u)
const;}
xs operator*(
const db &u)
const;}
}a[n]
,b[n]
,af[n]
,bf[n]
,as[n]
,bs[n]
,ans[n]
;vector<
int>an;
inline
intzh
(char u)
inline
void
fft(xs *a,
bool dft);if
(!dft) dw.xs*=-
1;for(j=
0;j=(i<<1)
);for(k=j;k}if
(!dft)
for(i=
0;i) a[i]
.ss/
=(db)l;
}int
main()
cin>>str;
for(i=
0;i)reverse
(b,b+n)
;reverse
(bf,bf+n)
;reverse
(bs,bs+n)
;for
(i=1
;i;l=(i<<1)
;for
(i=1
;i) rev[i]
=(rev[i>>1]
>>1)
|((i&1
)*l/2)
;fft
(a,1),
fft(b,1)
,fft
(af,1)
,fft
(bf,1)
,fft
(as,1)
,fft
(bs,1)
;for
(i=0
;i) ans[i]
=a[i]
*bs[i]
+as[i]
*b[i]
-af[i]
*bf[i]
*2.0
;fft
(ans,0)
;reverse
(ans,ans+n)
;for
(i=0
;i1;i++)if
(ans[i]
.sspush_back
(i+1);
cout
0;isize()
;i++
)}
BZOJ4259 殘缺的字串
其實大部分字串的題都可以用多項式來想,包括這道題。於是,我們可以嘗試去構造兩個多項式,使其乘後的係數為0即可。相等為0,那麼我們可以用減法表示。可 可以匹配所有的符號,我們又該咋辦?那不就相當於乘個0嘛。於是,我們得到了下式 然後就可以卷積計算了。include include include in...
bzoj 4259 殘缺的字串
這題好神啊,居然是fft,表示一直在往資料結構上想。把 當成0,那麼兩個串可以匹配當且僅當 sum a i b i 2 times a i times b i 0 我們可以把平方拆開,然後就變成了幾個乘積相加的形式,那就大力翻轉乙個串然後跑fft。因為最開始mle了所以複製貼上了好多東西。1 inc...
Bzoj4259 殘缺的字串
time limit 10 sec memory limit 128 mb submit 387 solved 93 很久很久以前,在你剛剛學習字串匹配的時候,有兩個僅包含小寫字母的字串a和b,其中a串長度為m,b串長度為n。可當你現在再次碰到這兩個串時,這兩個串已經老化了,每個串都有不同程度的殘缺...