[HDU2222] 关键字查询Keywords Search

来源:互联网 发布:cross over mac 编辑:程序博客网 时间:2024/05/21 17:32

题目描述

In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
Wiskey also wants to bring this feature to his image retrieval system.
Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.


输入格式

First line will contain one integer means how many cases will follow by.
Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
Each keyword will only contains characters ‘a’-‘z’, and the length will be not longer than 50.
The last line is the description, and the length will be not longer than 1000000.


输出格式

Print how many keywords are contained in the description.


样例数据

样例输入

1
5
she
he
say
shr
her
yasherhs

样例输出

3


题目分析

此题有毒,我至今还TLE。
AC自动机模板题。


源代码

#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;inline const int Get_Int() {    int num=0,bj=1;    char x=getchar();    while(x<'0'||x>'9') {        if(x=='-')bj=-1;        x=getchar();    }    while(x>='0'&&x<='9') {        num=num*10+x-'0';        x=getchar();    }    return num*bj;}const int maxn=500000;struct Tree {    int child[26],fail,tot; //fail失败指针    void clear() {        for(int i=0; i<26; i++)child[i]=0;        fail=0;        tot=0;    }};int root=1;struct Aho_Corasick_Automaton { //AC自动机    int cnt;    Tree tree[maxn];    void init() {        for(int i=0; i<=cnt; i++)tree[i].clear();        cnt=1;    }    void insert(char s[]) {        int now=root,len=strlen(s);        for(int i=0; i<len; i++) {            int j=s[i]-'a';            if(!tree[now].child[j]) {                tree[++cnt].clear();                tree[now].child[j]=cnt;            }            now=tree[now].child[j];        }        tree[now].tot++;    }    void buildfail() { //Bfs构造Fail指针        queue<int>Q;        Q.push(root);        while(!Q.empty()) {            int Now=Q.front();            Q.pop();            for(int i=0; i<26; i++) {                int Next=tree[Now].child[i];                if(Next==0)continue; //儿子不存在                Q.push(Next);                int fatherfail=tree[Now].fail; //父亲的失败指针                while(fatherfail&&!tree[fatherfail].child[i])fatherfail=tree[fatherfail].fail; //寻找可退回点                if(fatherfail)tree[Next].fail=tree[fatherfail].child[i]; //如果存在满足条件的点则设置失败指针                else tree[Next].fail=root; //否则指回root            }        }    }    int match(char s[]) { //匹配字符串s        int t=root,len=strlen(s),ans=0;        for(int i=0; i<len; i++) {            int j=s[i]-'a';            while(t&&!tree[t].child[j])t=tree[t].fail; //不匹配            if(t)t=tree[t].child[j]; //匹配            else t=root; //返回root            for(int j=t; j; j=tree[j].fail) {                ans+=tree[j].tot;                tree[j].tot=0;            }        }        return ans;    }};Aho_Corasick_Automaton ac;int t,n;int main() {    scanf("%d",&t);     while(t--) {        ac.init();        scanf("%d",&n);         for(int i=1; i<=n; i++) {            char s[1000005];            scanf("%s",&s);            ac.insert(s);        }        ac.buildfail();        char s[1000005];        scanf("%s",&s);        printf("%d\n",ac.match(s));    }    return 0;}

0 0