• AC自动机 模板


    AC自动机模板

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 1e6 + 500;
    const int inf = 1e9;
    
    int minv[maxn] , n ;
    char base[maxn] , str[maxn];
    
    struct AC_Auto{
        const static int LetterSize = 26;
    	const static int TrieSize = 26 * ( 1e5 + 50); 
    	int tot;
    	int fail[TrieSize]; 
    	int suffixlink[TrieSize]; 
    
    	struct node{
    		int ptr[LetterSize];
    		int val;
    	}tree[TrieSize];
    
    	inline int GetLetterIdx(char c){
    		return c - 'a';
    	}
    
    	void init_node(node & s){
    		memset( s.ptr , 0 , sizeof( s.ptr ) );
    		s.val = 0;
    	}
    
    	void find(const char * str){
    		int len = strlen( str );
    		int j = 0;
    		for(int i = 0 ; i < len ; ++ i){
    			int idx = GetLetterIdx( str[i] );
    			while(j && !tree[j].ptr[idx]) j = fail[j];
    			j = tree[j].ptr[idx];
    			if(suffixlink[j]) minv[i] = suffixlink[j];
    			else minv[i] = 0;
    		}
    	}
    
    	void insert(const char * str){
    		int len = strlen( str );
    		int cur = 0;
    		for(int i = 0 ; i < len ; ++ i){
    			int idx = GetLetterIdx( str[i] );
    			if(!tree[cur].ptr[idx]){
    				tree[cur].ptr[idx] = tot;
    				init_node( tree[tot++] );
    			}
    			cur = tree[cur].ptr[idx];
    		}
    		if(tree[cur].val == 0) tree[cur].val = len;
    		else tree[cur].val = min( tree[cur].val , len );
    	}
    
    	void build_fail(){
    		queue < int > Q; // 开在栈中 , 如果节点数较多 , 可设为全局变量
    		suffixlink[0] = fail[0] = 0;
    		for(int i = 0 ; i < LetterSize ; ++ i)
    			if(tree[0].ptr[i]){
    				int index = tree[0].ptr[i];
    				fail[index] = 0 , suffixlink[index] = tree[index].val;
    				Q.push( index );
    			}
    		while(!Q.empty()){
    			int x = Q.front() ; Q.pop();
    			for(int i = 0 ; i < LetterSize ; ++ i)
    				if(tree[x].ptr[i]){
    					int v = tree[x].ptr[i];
    					int j = fail[x];
    					while( j && !tree[j].ptr[i] ) j = fail[j];
    					fail[v] = tree[j].ptr[i];
    					suffixlink[v] = suffixlink[fail[v]];
    					if(suffixlink[v] == 0){
    						if(suffixlink[x]) suffixlink[v] = suffixlink[x] + 1;
    					}
    					else if(suffixlink[x]) suffixlink[v] = min( suffixlink[v] , suffixlink[x] + 1 );
    					if(tree[v].val){
    						if(suffixlink[v]==0) suffixlink[v] = tree[v].val;
    						else suffixlink[v] = min( suffixlink[v] , tree[v].val );
    					}
    					Q.push( v );
    				}
    		}
    	}
    
    	void init(){ tot = 1 ; init_node( tree[0] );}
    
    }ac_auto;
    
    int main(int argc,char *argv[]){
    	int Case , cas = 1;
    	scanf("%d" , &Case);
    	while(Case--){
    		scanf("%s%d",base,&n);
    		ac_auto.init();
    		for(int i = 0 ; i < n ; ++ i){
    			scanf("%s" , str);
    			ac_auto.insert( str );
    		}
    		ac_auto.build_fail();
    		ac_auto.find( base );
    		int len = strlen( base );
    		long long ans = 0 ;
    		int last = 0;
    		for(int i = 0 ; i < len ; ++ i){
    			if(minv[i] == 0) ans += ( i - last + 1 );
    			else ans += minv[i] - 1 , last = max( last , i + 2 - minv[i] );
    		}
    		printf("Case #%d: %lld
    " , cas++ , ans );
    	}
    	return 0;
    }
  • 相关阅读:
    万字长文|Hadoop入门笔记(附资料)
    大数据最后一公里——2021年五大开源数据可视化BI方案对比
    非结构化数据怎么存?——开源对象存储方案介绍
    (三、四)Superset 1.3图表篇——透视表-Pivot Table
    数据湖搭建指南——几个核心问题
    (二)Superset 1.3图表篇——Time-series Table
    DorisDB升级为StarRocks,全面开源!
    (一)Superset 1.3图表篇——Table
    HCNP Routing&Switching之BGP基础
    HCNP Routing&Switching之路由引入导致的问题及解决方案
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5582672.html
Copyright © 2020-2023  润新知