洛谷 P2292 AC自動機 狀態壓縮

2021-10-23 11:25:16 字數 1565 閱讀 3361

題目問,給定 n

nn 個模式串,問你主串的 「可理解的」 最長字首長度。「可理解的」 意思指可以被分成若干個模式串。

首先我們知道ac自動機,fai

lfail

fail

指標跳轉的是相同字尾,在跳轉的過程中會依據長度從大到小經過相同的字尾。比如 abc

d−

−>bc

d−

−>

dabcd -- >bcd - ->d

abcd−−

>bc

d−−>d。

在該題中,假設主串當前長度為 k

kk 的字尾,可以在 fai

lfail

fail

樹上找到乙個以該字元為結束的長度相同的字尾,則可以發生 f[i

]=f[

i]

f[i]=f[i]

f[i]=f

[i]∣|∣f

[i−k

]f[i-k]

f[i−k]

的狀態轉移,f

ff 表示可以「可理解」。

那麼我們要對於不同長度的字尾都做乙個狀態轉移,則需要做個狀態壓縮,因為模式串長度 ∣s∣

≤10

|s|\leq10

∣s∣≤10

,所以我們可以用 int

intin

t 型資料,以二進位制來表示。

我們在建自動機時做預處理,維護乙個 dpdp

dp陣列,用於存貯模式串的狀態,先繼承 fai

lfail

fail

指標跳轉的所有字尾狀態。且當前若為結束位置,則將自身狀態加入其中。

**如下:

#include

#define endl '\n'

using

namespace std;

typedef

long

long ll;

const

int maxn =

2e6+5;

const

int lens =

2e4+5;

int cnt;

int tr[lens][26

], isend[lens]

, fail[lens]

;int dp[lens]

, depth[lens]

;char mo[

200]

[200

], text[maxn]

;void

insert

(char s,

int no)

isend[p]++;

}void

build()

while

(!q.

empty()

)else

tr[k]

[i]= tr[fail[k]

][i];}

}}intmain()

build()

;while

(m--)}

cout << ans << endl;

}}

洛谷 P 2292 L語言 AC自動機

一道比較簡單的題,結果自己腦補了各種奇葩 錯誤 的判斷,搞了乙個多小時。題意 用已知字典去識別乙個串,求最長可識別字首 指能將此字首分解為字典裡面的單詞 思路 建好ac自動機,記錄好每個點所代表的字串的長度 拿要匹配的串從前往後匹配,若某個點完全不能匹配,直接退出 可以不考慮這個 處理好什麼叫 可以...

AC自動機 洛谷P3808 AC自動機(簡單版)

給定 n n 個模式串和1個文字串,求有多少個模式串在文字串裡出現過 多模匹配用ac role presentation aca c自動機 首先建造一棵字典樹,新增所有模式串,然後建造失配指標,最後進行匹配 luogu judger enable o2 include include include...

AC自動機入門,洛谷P3808

給定n個模式串和1個文字串,求有多少個模式串在文字串裡出現過。輸入輸出格式 輸入格式 第一行乙個n,表示模式串個數 下面n行每行乙個模式串 下面一行乙個文字串。輸出格式 乙個數表示答案 輸入輸出樣例 輸入樣例 1 2aaa aa輸出樣例 1 兩個會出現在模板題面裡的詞語 文字串和模式串 給你幾個單詞...