洛谷 P4173 殘缺的字串 FFT

2022-05-31 01:36:08 字數 1911 閱讀 4897

給定長度為 \(m\) 的模式串和長度為 \(n\) 的目標串,兩個串都帶有萬用字元,求所有匹配的位置。

fft

帶有萬用字元的字串匹配問題。

設模式串為 \(p\),目標串為 \(t\),將兩個串的內容都根據字母先後順序對映到 \(1\) 到 \(26\)。

如果不帶有萬用字元,那麼 \(t\) 以第 \(k\) 位結束的長度為 \(|p|\) 的子串與 \(p\) 匹配時有

\[\sum_^ (p[i] - t[k - |p| + 1 + i])^2 = 0

\]如果帶有萬用字元,只需將上式稍微改一下就行。

讓兩個串中的所有萬用字元對映到 \(0\),設匹配結果為 \(f\),則有

\[f[i] = \sum_^ (p[i] - t[k - |p| + 1 + i])^2 \cdot p[i] \cdot t[k - |p| + 1 + i]

\]接下來翻轉 \(p\) 串 (\(fft\) 的套路),設 \(r[|p| - i - 1] = p[i]\),則有

\[f[i] = \sum_^ (r[|p| - i - 1] - t[k - |p| + 1 + i])^2 \cdot r[|p| - i - 1] \cdot t[k - |p| + 1 + i]

\]下標加起來等於 \(k\),令 \(j = |p| - i - 1\),則

\[f[i] = \sum_ (r[j] - t[i])^2 \cdot r[j] \cdot t[i]

\]展開後有

\[f[i] = \sum_ (r[j]^3t[i] + t[i]^3r[j] - 2\cdot r[j]^2t[i]^2)

\]用 \(fft\) 分別求一下卷積即可。

#include using namespace std;

const double pi = acos(-1);

const double eps = 1e-8;

typedef complexcomplex;

const int maxn = 2e6 + 10;

complex p[maxn], t[maxn];

complex a[maxn], b[maxn], c[maxn], d[maxn];

complex ans[maxn];

string str;

int m, n;

int bit = 2, rev[maxn];

void get_rev()

}void fft(complex *a, int op)

for(int mid = 1; mid < bit; mid <<= 1) }}

}int main()

cin >> str;

for(int i = 0; i < n; ++i)

get_rev();

for(int i = 0; i < bit; ++i)

fft(a, 1); fft(b, 1);

for(int i = 0; i < bit; ++i)

for(int i = 0; i < bit; ++i)

fft(a, 1); fft(b, 1);

for(int i = 0; i < bit; ++i)

for(int i = 0; i < bit; ++i)

fft(a, 1); fft(b, 1);

for(int i = 0; i < bit; ++i)

fft(ans, -1);

queueq;

for(int i = m - 1; i < n; ++i)

cout << q.size() << endl;

while(q.size())

cout << endl;

return 0;

}

洛谷 P4173 殘缺的字串

不知道xjb kmp可不可以做的說 假設下標都以0開頭 對於有一定偏移量的序列的 對應位置 匹配或者數值計算的題,這裡是有一種套路的,就是把其中乙個序列翻轉過來,然後卷積一下,所得到的新序列c的每乙個位置就包含了 所有原來一定偏移量的位置的乘積和。對於這個題,我們只需要找到一種方法,使相同的字元代表...

洛谷P4173 殘缺的字串

很久很久以前,在你剛剛學習字串匹配的時候,有兩個僅包含小寫字母的字串 a 和 b 其中 a 串長度為 m b 串長度為 n 可當你現在再次碰到這兩個串時,這兩個串已經老化了,每個串都有不同程度的殘缺。你想對這兩個串重新進行匹配,其中 a 為模板串,那麼現在問題來了,請回答,對於 b 的每乙個位置 i...

P4173 殘缺的字串 FFT

給出兩個字串 s,t 其中包含小寫字母和一些 可以匹配任何字元。求有多少個 p 使得 t s 如果不考慮 我們可以用做差法來匹配兩個字元,構造匹配函式 f x sum t i s 2 這樣若 f x 0 證明它們在位置 x 處匹配。但是現在有 也就是要跳過有 的位置,定義 的值為 0 然後改一下匹配...