ac自動機:
給你若干個單詞,判斷一段文字裡邊這些單詞出現了嗎,在哪出現,出現幾次?
首先是字典樹模板:
#include#define debug printf("!");view codeusing
namespace
std;
const
int maxn=1e3+50
;struct
trie_node;
trie_node*new_node()
void trie_insert(trie_node *root,char
key)
node->count+=1;}
int trie_search(trie_node *root,char
key)
if(node==null)return0;
else
return node->count;
}int
main()
while(q--)
}
時隔幾個月,覺得上面那個模板好醜,搬了oiwiki的板子:
structview codetrie
exist[p] = 1
; }
bool find(char *s, int l)
return
exist[p];
}};
然後是ac自動機:字典樹+fail指標 重點在getfail函式
例題是 hdu5880
一整天,一直被卡mle,改成指標形式的動態開點也卡。
然後去搜,終於搜到一篇部落格。
部落格說:不要一次性memset,而是,用到乙個點,memset一次。
#include#includeview code#include
#include
#define debug printf("!");
using
namespace
std;
const
int maxn=1e6+5
;struct
tac[maxn];
intcnt;
char
s[maxn];
void init(int
t)inline
void insert(char *s)
p=ac[p].vis[s[i]-'a'
]; }
ac[p].dep=dep;
}inline
void
get_fail()
}while(!que.empty())
else ac[u].vis[i]=ac[ac[u].fail].vis[i];}}
}void query(char
s) p=ac[p].vis[c-'a'
];
for(j=p;j;j=ac[j].fail)}}
}int
main()
get_fail();
getchar();
cin.getline(s,maxn);
query(s);
printf(
"%s\n
",s);}}
(上面的板子也不好看●﹏● 用下面的:
例題: 破忒頭的匿名信
#includeusingview codenamespace
std;
typedef
long
long
ll;const
int maxn=5e5+5
;ll f[maxn];
intval[maxn],dep[maxn];
struct
ac dep[p]=len;
if(!val[p])val[p]=w;
val[p]=min(val[p],w);
}void
getfail()}}
void query(char s,int
len)}}
}ac;
char
s[maxn];
intmain()
ac.getfail();
scanf("%s
",s+1
); len=strlen(s+1
);
for(int i=1;i<=len;i++)f[i]=1e16;
ac.query(s,len=strlen(s+1
)); printf(
"%lld\n
",f[len]==1e16?-1
:f[len]);
}
AC自動機模版 字串
ac自動機主要用於解決多模式串的匹配問題 具體指的是 如下圖中 模式串 p中有多個 字串,問這些字串在 主串s的出現的總次數 是字典樹 trie樹 的變種,一種偽樹形結構 主體是樹形的,但是由於加入了失敗指標,使得它變成了乙個有向圖 以當前節點為終點的 模式字串 的數量 int fail 1 fai...
字串 2 AC自動機
ac自動機,其實就是trie樹與kmp的結合,且有dfa 有限狀態機 的性質.理解的關鍵點 1.fail指標 起到回溯作用 2.每次匹配都是主串不動,移動指標now去回溯找字尾的字首 3.乙個優化點,將null指向root 編碼更簡單.考察時一般也會問道dfa的性質.ac自動機解決問題 1.多模式串...
字串應用之AC自動機
ac 自動機的用處 查詢目標串中出現了哪些模式串 即文字字串 s 中出現了哪些字典中的單詞 一種字串上的 dp fail 樹應用 ac 自動機的演算法分三步 構建所有 單詞 的 trie 樹 構建失配指標 模式匹配過程 1.void trie is end now true 2.自動機中乙個節點 p...