ac自動機,模板題
本題要點:
1、把多個病毒串,建立 trie, 其中陣列virus_id[k] 表示節點是k的點對應的病毒編號
2、建立 fail 陣列
3、有m個文字串,沒依次查詢,都會把陣列virus_id[k]對應的值賦值為0,防止重複遍歷。
所以,查詢完後,需要把陣列 virus_id 的資料恢復原來的樣子。我這裡用的很 low
的方法,直接開乙個 陣列 virus_id 的副本 virus_id1 。
4、一些注意的地方:
字串是可見字元,並不只是小寫字母。
字典樹是 trie[maxl][128], 而不是 trie[maxl][26]。
訪問某個節點下的 128 個節點,不要寫成 int next = s[i] - 『a』;
應該寫 int next = s[i];
#include
#include
#include
#include
#include
using
namespace std;
const
int maxn =
510, maxl =
100010
;char virus[maxn]
[210
], web[maxl]
;int n, m;
int trie[maxl]
[128];
int virus_id[maxl]
;//virus_id[k] 表示節點是k的點對應的病毒編號 //不同編號的病毒特徵碼不會相同
int virus_id1[maxl]
;int fail[maxl]
;int cnt =0;
int ans[maxn]
, virus_num;
void
inserwords
(char s,
int len,
int id)
root = trie[root]
[next];}
virus_id1[root]
= virus_id[root]
= id;
}void
getfail()
}while
(!q.
empty()
)else}}
}void
query
(char s,
int len)
}memcpy
(virus_id, virus_id1,
sizeof virus_id1);}
intmain()
getfail()
;scanf
("%d"
,&m)
;int tol =0;
for(
int i =
1; i <= m;
++i)
printf
("\n");
}}printf
("total: %d\n"
, tol)
;return0;
}/*3aaa
bbbccc
2aaabbbccc
bbaacc
*//*
web 1: 1 2 3
total: 1
*/
hdu2896 AC自動機 病毒侵襲
同樣是一道很裸的ac自動機,統計哪些特徵碼出現在 的原始碼上,匹配成功時不要將val賦值為0,因為後面還有文字串要匹配,另外要注意編號需要從小到大輸出。include include includeusing namespace std const int maxn 100000 10 const ...
hdu 2896 病毒侵襲 AC自動機
hdu 2896 題目大意 給出n個模式串,最後給出m個主串 問有主串出現過哪些模式串,最後輸出哪些主串能匹配模式串 解題思路 ac自動機建立字典樹的用w值標記第幾個模式串 定義k值,匹配時若字典樹中的某個結點不等於k且w不為0則記錄該點 有多個主串需要匹配,所以不需要改變w的值,但可以判斷k的值 ...
hdu 2896 病毒侵襲 ac自動機
include include include using namespace std define maxnode 100100 define sigma size 135 int ch maxnode sigma size int f maxnode fail函式 int val maxnode...