BZOJ 1212 [HNOI2004] L语言 AC自动机+DP
2017-01-17 09:18
323 查看
题目大意:给出n个模式串,接着给出m个主串,求每个主串中的一个最长前缀使得其能被分割成若干个模式串。
Trie树上暴力时间复杂度O(1M*10*20),过亿应该就很卡了吧…但是也能过,不过写AC自动机稳一点吧。
设状态f(i)为长度为i的前缀是否能通过几个模式串表示出来。模式串建成AC自动机,结点上记录这个串的长度,用主串在上面跑,若匹配到了一个长度为j的串,则f(i) |= f(i-j).
需要注意的是,一个结点中本身没有串但是在它的fail指针中可能含有串,所以在getFail中需要用fail指针的val值更新自己的val值。因为是bfs,当前点表示的串一定是目前最长的,而跳fail是往前跳,所以取max就一定不会出现本身代表一个串却被更新的情况。
Trie树上暴力时间复杂度O(1M*10*20),过亿应该就很卡了吧…但是也能过,不过写AC自动机稳一点吧。
设状态f(i)为长度为i的前缀是否能通过几个模式串表示出来。模式串建成AC自动机,结点上记录这个串的长度,用主串在上面跑,若匹配到了一个长度为j的串,则f(i) |= f(i-j).
需要注意的是,一个结点中本身没有串但是在它的fail指针中可能含有串,所以在getFail中需要用fail指针的val值更新自己的val值。因为是bfs,当前点表示的串一定是目前最长的,而跳fail是往前跳,所以取max就一定不会出现本身代表一个串却被更新的情况。
#include <cstdio> #include <cstring> #include <queue> #define Max(a,b) (a>b?a:b) using namespace std; struct Node { Node *ch[26],*nxt; int val; Node():nxt(0x0),val(0) {memset(ch,0,sizeof ch);} }*root=new Node(); int n,m; char s[1000005]; bool jud[1000005]; void Insert() { int len=strlen(s); Node* o=root; for(int i=0;i<len;i++) { int z=s[i]-'a'; if(!o->ch[z]) o->ch[z]=new Node(); o=o->ch[z]; } o->val=len; return ; } void getFail() { static queue<Node*> q; Node* o=root; for(int i=0;i<26;i++) if(o->ch[i]) q.push(o->ch[i]) , o->ch[i]->nxt=o; else o->ch[i]=o; while(!q.empty()) { o=q.front(); q.pop(); for(int i=0;i<26;i++) if(o->ch[i]) q.push(o->ch[i]) , o->ch[i]->nxt=o->nxt->ch[i]; else o->ch[i]=o->nxt->ch[i]; Node* tmp=o->nxt; while(tmp!=root && !tmp->val) tmp=tmp->nxt; o->nxt=tmp; o->val=Max(o->val,tmp->val); } return ; } void Match() { Node* o=root; int len=strlen(s+1); for(int i=1;i<=len;i++) { int z=s[i]-'a'; o=o->ch[z]; if(o->val) { Node* tmp=o; while(tmp!=root) jud[i]|=jud[i-tmp->val] , tmp=tmp->nxt; } } return ; } int main() { scanf("%d%d",&n,&m); while(n--) scanf("%s",s) , Insert(); getFail(); while(m--) { memset(jud,false,sizeof jud); jud[0]=true; scanf("%s",s+1); Match(); int i; for(i=strlen(s+1);i;i--) if(jud[i]) break; printf("%d\n",i); } return 0; }
相关文章推荐
- bzoj 1212 [HNOI2004]L语言
- [HNOI2004][bzoj1212] L语言 [Trie+dp]
- bzoj1212 [HNOI2004]L语言(Trie+暴力)
- [BZOJ1212]-[HNOI2004]L语言-trie+DP
- [BZOJ1212][HNOI2004]L语言
- 【BZOJ】1212 [HNOI2004]L语言 Trie
- BZOJ 1212 HNOI 2004 L语言 Trie树
- BZOJ1212 [HNOI2004]L语言
- BZOJ1212 [HNOI2004] L语言
- bzoj1212: [HNOI2004]L语言
- [BZOJ1212][HNOI2004]L语言(AC自动机+dp)
- bzoj1212: [HNOI2004]L语言 Trie+dp
- bzoj1212 [HNOI2004]L语言(AC+dp)
- 【Trie】bzoj1212 [HNOI2004]L语言
- Bzoj1212: [HNOI2004]L语言
- 【BZOJ1212】[HNOI2004]L语言 Trie树
- BZOJ 1212 HNOI2004 L语言 AC自己主动机(Trie树)+动态规划
- bzoj1212: [HNOI2004]L语言
- bzoj 1212 [HNOI2004] L语言(不用AC自动机)
- BZOJ_1212_[HNOI2004]L语言_哈希