洛谷 P3966 單詞 AC自動機

2022-05-07 22:00:11 字數 1866 閱讀 9477

因為文字串就是字典本身,所以這個和平時的ac自動機不太一樣。平時的query要沿著fail樹把子樹的出現次數依次統計。但是這個的query就是對每個字典裡的字串搞一次。所以就直接按廣搜的順序反過來樹形dp統計出子樹中的出現次數,直接回答。

#includeusing namespace std;

typedef long long ll;

const int maxn = 1e6;

const int maxm = 2e2;

int idx[maxm + 5];

struct trie

void init()

void insert(char buf, int id)

idx[id] = cur;

}void build()

}while(head < tail) }}

for(int i = tail - 1; i >= 0; i--)

}};char buf[maxn + 5];

trie ac;

int main()

ac.build();

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

printf("%d\n", ac.cnt[idx[i]]);

}

這種寫法是,每次文字串遇到乙個模式串,就會給這個模式串+1次出現次數。問題是怎麼優化重複的文字串呢?把文字串插入另乙個trie裡面就可以知道他們的重複數。然後每次就給每個模式串都貢獻乙個重數就等價了。這樣最好理解。優化的地方在於同樣的文字串不用多次匹配。

#includeusing namespace std;

typedef long long ll;

const int maxn = 1e6;

const int maxm = 2e2;

int ans[maxm + 5];

int aidx[maxn + 5][maxm + 5];

struct trie

void init()

void insert(char buf, int id)

cnt[cur]++;

//本題中文字可以一併插入,乾脆合併成乙個cnt,可以在同乙個trie中,否則應該分開插入兩個trie

aidx[cur][cnt[cur]-1] = id;

}void build()

}while(head < tail) }}

}void query(char buf)

}return res;*/

//該種文字串對所有模式串貢獻了幾次?

//插好所有文字之後得到文字的重數,對每個文字在trie中o(n)找出他的重數以及他有沒有被vis

//沒有被vis的話就對每個匹配的模式貢獻對應的重數

int len = strlen(buf);

int cur = root;

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

if(vis[cur])

return;

int cf = cnt[cur];

vis[cur]=1;

cur = root;

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

temp = fail[temp];}}

}};char buf[maxm+5][maxn + 5];

trie ac;

int main()

ac.build();

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

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

printf("%d\n", ans[i]);

}

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 兩個會出現在模板題面裡的詞語 文字串和模式串 給你幾個單詞...

AC自動機模板 洛谷3796

ac自動機的第三個模板 其實,個人覺得,目前我寫的這三個不同的模板完全是可以合併在一起求解的。只是,在這兩個無關聯的oj上,同乙個ac自動機都可以完成的問題被拆成了三道題而已。因此,只需要略加修改即可解決這道題。具體題目請上洛谷檢視 include include include include i...