HU 2222:Keywords Search(AC自動機テンプレート)


Keywords Search
Time Limit:2000/1000 MS(Java/Others)    Memory Limit:13131313137272 K(Java/Others)Total Submission(s):81284    Acceepted Submission(s):28367
テーマリンク:http://acm.hdu.edu.cn/showproblem.php?pid=2222
Description:
In the modent time,Search engine came into the life of everbody like Google,Baidu,etc.Wisky also wants to bring this feature to his image retrieval system.Every marge have a long description,whemationthe system will match the keywors with description of image and show the mage which the most keywors be matched.To simplify the proble m,giving you a description of image,and some keywords,you shound tworket hold matworkew.match.twork.twork.twork.twork.twork.tch.tch.twork.two
Input:
First line will contain one integer means how many cases will followow by.Each case will contain tworket integers N means the number of keywords follow.(N==10000)Each keyword will contronly the the ingners's charactinners's's。and the length will be not longer than 100000.
Output:
Print how many keywords are contained in the description.
Sample Input:
1
5
she
he
say
shr
her
yasherhs
Sample Output:
3
件名:
与えられた文字列にマッチする文字列はどれぐらいありますか?
 
クイズ:
マルチモードマッチング問題は、AC自動機に直接行けばいいです。
コードは以下の通りです
#include 
#include 
#include <string>
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 500005,M = 26;
int t;
int n;
queue <int> q;
char s[55],str[1000005];
struct Aho_Corasick{
    int Size;
    int ch[N][M];
    int val[N];
    int fail[N];
    void init(){
        Size=-1;
        newnode();
    }
    int newnode(){
        memset(ch[++Size],0,sizeof(ch[0]));
        val[Size]=fail[Size]=0;
        return Size;
    }
    void insert(char *s){
        int l=strlen(s);
        int u=0;
        for(int i=0;i){
            int idx=s[i]-'a';
            if(!ch[u][idx]) ch[u][idx]=newnode();
            u=ch[u][idx];
        }
        val[u]++;
    }
    void Getfail(){
        while(!q.empty()) q.pop();
        for(int i=0;i<26;i++){
            if(ch[0][i]) q.push(ch[0][i]);
        }
        while(!q.empty()){
            int cur=q.front();q.pop();
            for(int i=0;i<26;i++){
                if(ch[cur][i]){
                    fail[ch[cur][i]]=ch[fail[cur]][i];
                    q.push(ch[cur][i]);
                }else{
                    ch[cur][i]=ch[fail[cur]][i];
                }
            }

        }
    }
    int query(char *s){
        int ans = 0,u = 0;
        int l=strlen(s);
        for(int i=0;i){
            int idx = s[i]-'a';
            int cur = ch[u][idx];
            int tmp=cur;
            while(tmp && val[tmp]>=0){
                ans+=val[tmp];
                val[tmp]=-1;
                tmp=fail[tmp];
            }
            u=cur;
        }
        return ans ;
    }
}ac;
int main(){
    scanf("%d",&t);
    while(t--){
        ac.init();
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            ac.insert(s);
            int l=strlen(s);
        }
        ac.Getfail();
        scanf("%s",str);
        int ans = ac.query(str);
        printf("%d
",ans); } return 0; }
 
転載先:https://www.cnblogs.com/heyuhhh/p/10479845.html