BZOJ4259 殘缺的字串(FFT)

2022-05-21 23:18:12 字數 1251 閱讀 6488

兩個串匹配時相匹配的位置位置差是相同的,那麼翻轉乙個串就變成位置和相同,卷積的形式。

考慮如何使用卷積體現兩個位置能否匹配。乙個暴力的思路是每次只考慮一種字元,將其在乙個串中設為1,並在另乙個串中將不是該字元且不是萬用字元的設為1,卷積結果不為0則無法匹配。這樣要跑26次1e6的fft,就算有6s也……事實上這在luogu就可以過了。

當然這是因為luogu的評測機太神了,我們考慮一些更靠譜的方法。考慮用一些奇技淫巧。

定義兩個字串的距離函式為dis(a,b)=σ(a[i]-b[i])2a[i]b[i]。萬用字元在字串中視為0。可以發現這個式子非常妙的將通配和直接匹配都包括進去了,不同位置間不會相互影響,如果dis=0則相同≠0則不同。將這個式子展開,做三次fft再加起來就可以了。

居然最慢的只跑了半秒……

#include#include

#include

#include

#include

#include

using

namespace

std;

intread()

while (c>='

0'&&c<='

9') x=(x<<1)+(x<<3)+(c^48),c=getchar();

return x*f;

}#define n 1050000

intn,m,r[n],t;

char

s1[n],s2[n];

bool

f[n];

double

s[n];

const

double pi=3.14159265358979324

;const

double eps=1e-2

;struct

complex

; }

complex

operator -(const complex&a) const

; }

complex

operator *(const complex&a) const

; }

}a[n],b[n];

void dft(int n,complex *a,intp);

for (int j=0;ji)

;for (int k=j;k>1);k++,w=w*wn)}}

}void mul(int n,complex *a,complex *b)

intmain()

BZOJ4259 殘缺的字串

給出兩個字串,乙個模式串,乙個匹配串,問匹配串中哪些位置可以匹配上模式串,其中 可以作任意字元。這個可以轉化為多項式,我們可以把 看作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 ...

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...