TJOI 2013 單詞(AC自動機)

2021-08-03 20:25:21 字數 1627 閱讀 3319

題目背景

tjoi2013 day1 t3

題目描述

小張最近在忙畢業**設計,所以一直在讀**。一篇**是由許多單詞組成的。

但小張發現乙個單詞會在**中出現很多次,他想知道每個單詞分別在**中出現多少次。

輸入格式

第一行乙個整數 n (n≤200),表示有 n 個單詞。接下來 n 行每行乙個單詞。每個單詞都由小寫字母(』a』~』z』)組成。

所有單詞構成**(一行乙個單詞)。

輸出格式

輸出 n 個整數,第 i 行的數字表示第 i 個單詞在文章中出現了多少次。

樣例資料 1

輸入 3

a aa

aaa

輸出 6 3 1

備註 【資料範圍】

30%„ 的資料,單詞總長度不超過 10^3 ;

100% 的資料,單詞總長度不超過 10^6 。

讀完題後我們不難發現這是一道ac自動機的題,如果不會ac自動機請參考ac自動機演算法;ac自動機模板

假設現在大家都會ac自動機:

首先我們需要把所有的單詞都存到乙個字元陣列裡來表示文章,每個單詞中間可以用一些小符號隔開來表示不同的單詞,例如 『a』+26,輸出為 <;

然後我們就構建tri樹,和fail指標;

然後直接匹配,具體過程見**

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

//---------------------

char s[1000050],s1[1000050];

int now,pos,n,l,len,f[1000050][27],tot,tag[1000050];

int fail[1000050],next[1000050],nt,first[1000050],ans[1000050];

int head=0,tail=1,q[1000050];

//---------------------

inline void f1() //構建tri樹

}//---------------------

inline void ac()

}//---------------------

int main()

ac(); //構建fail指標

for(;pos

pos++) tag[now=f[now][s1[pos+1]-'a']]++; //掃一遍統計每個字母在文章中出現的次數

for(int i=tail;i;i--) tag[fail[q[i]]]+=tag[q[i]]; //因為當前的字元會在它的fail指標處再出現,所以需要累加,例如樣例中的a 出現6次

bool asdf=0; //判斷是否為第乙個空格

int t=0;

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

else t=f[t][s1[i]-'a'];

}coutreturn

0;}

單詞統計 AC自動機

1118.單詞統計 time limit 1000 ms memory limit 32768 kb total submission s 12 accepted submission s 1 description 給定乙個字串和若干個單詞,統計這些單詞在這個字串中出現的次數。input 第一行為...

AC自動機 建立nlogn個AC自動機

string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...

BZOJ 3172 單詞 (AC自動機)

這道題是個裸的ac自動機,但是我還是調了很久qaq。首先如果我們直接用每個單詞來匹配的,時間不是很理想。這道題要用到ac自動機的衍生物 fail樹 我也是做這道題才知道有這個東西 fail樹有這麼乙個結論 乙個字串出現的次數等於以它為根節點的fail樹的子樹中所有節點的cnt的和。根據這個結論,我們...