• HDU-2222 Keywords Search(AC自动机--模板题)


    题目大意:统计一共出现了多少次模板串。

    题目分析:AC自动机的模板题。不过这题有坑,相同的模板串不能只算一次。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<queue>
    # include<map>
    # include<string>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=10000;
    
    int ch[N*50+5][26];
    int val[N*50+5];
    int last[N*50+5];
    int f[N*50+5];
    bool mark[N*50+5];
    map<string,int>mp;
    string str[N+5];
    
    struct AC
    {
    	int cnt,res;
    	void init()
    	{
    		res=cnt=0;
    		memset(ch,0,sizeof(ch));
    		memset(val,0,sizeof(val));
    		memset(mark,false,sizeof(mark));
    	}
    	int idx(char c)
    	{
    		return c-'a';
    	}
    	void insert(string str,int v)
    	{
    		int u=0;
    		int n=str.size();
    		for(int i=0;i<n;++i){
    			int c=idx(str[i]);
    			if(!ch[u][c]) ch[u][c]=++cnt;
    			u=ch[u][c];
    		}
    		val[u]=v;
    	}
    	void getFail()
    	{
    		queue<int>q;
    		f[0]=0;
    		for(int i=0;i<26;++i){
    			int u=ch[0][i];
    			if(!u) continue;
    			f[u]=0;
    			q.push(u);
    			last[u]=0;
    		}
    		while(!q.empty())
    		{
    			int r=q.front();
    			q.pop();
    			for(int i=0;i<26;++i){
    				int u=ch[r][i];
    				if(!u){
    					ch[r][i]=ch[f[r]][i];
    				}else{
    					q.push(u);
    					int v=f[r];
    					while(v&&!ch[v][i]) v=f[v];
    					f[u]=ch[v][i];
    					last[u]=val[f[u]]?f[u]:last[f[u]];
    				}
    			}
    		}
    	}
    	void ac(string str)
    	{
    		int n=str.size();
    		int j=0;
    		for(int i=0;i<n;++i){
    			int c=idx(str[i]);
    			j=ch[j][c];
    			if(val[j]) print(j);
    			else if(last[j]) print(last[j]);
    		}
    	}
    	void print(int u)
    	{
    		if(u){
    			if(!mark[val[u]]) res+=mp[str[val[u]]];
    			mark[val[u]]=true;
    			print(last[u]);
    		}
    	}
    	int getResult()
    	{
    		return res;
    	}
    }ac;
    
    char s[N*100+5];
    
    int main()
    {
    	int T,n;
    	scanf("%d",&T);
    	while(T--)
    	{
    		mp.clear();
    		scanf("%d",&n);
    		ac.init();
    		for(int i=1;i<=n;++i){
    			cin>>str[i];
    			++mp[str[i]];
    			ac.insert(str[i],i);
    		}
    		scanf("%s",s);
    		ac.getFail();
    		ac.ac(s);
    		printf("%d
    ",ac.getResult());
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    机器学习笔记1
    Matlab学习日记之基础知识
    Matlab学习日记之操作界面
    Matlab学习日记之绘图
    Matlab学习日记之数学应用
    Matlab学习日记之映像
    机器学习笔记4
    机器学习笔记2
    在线CHM阅读器(2)——文件提取及关键文件解析
    一步一步打造WebIM(1)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5754416.html
Copyright © 2020-2023  润新知