10 Sep 2016

AC自动机试水

这是一个板子页面

比他们慢了快一年,终于开始学AC自动机了。。

不知道为什么他们博客里都各种试水试水的搞得我好尴尬

话说老外的板子真好看


HDU2222这题号也真是二

敲完这道题也就大概知道自动机的原理以及自动在哪里。。

Code

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
const int N=5e5;
const int M=1e6+5;
#define bug(x) cout<<#x<<"="<<x<<" "
#define debug(x) cout<<#x<<"="<<x<<endl
char str[M];
struct trie{
	struct node{
		int to[26],g,d;
	}tr[M];
	int allc,que[N];
	inline void clear(){
		for(int i=1;i<=allc;++i){
			for(int j=0;j<26;++j)
				tr[i].to[j]=0;
			tr[i].d=0;
		}
		allc=1;
	}
	inline void Insert(int len){
		int rt=1;
		for(int i=0;i<len;++i){
			if(!tr[rt].to[str[i]])
				tr[rt].to[str[i]]=++allc;
			rt=tr[rt].to[str[i]];
		}
		tr[rt].d+=1;
	}
	inline void build(){
		int l=0,r=0;
		for(que[r++]=1;l<r;){
			int v=que[l++];
			for(int i=0;i<26;++i){
				int j,s;
				for(j=tr[v].g;j;j=tr[j].g)
					if(tr[j].to[i])break;
						//沿着祖宗们的失配函数跳啊跳,调到祖宗的失配函数也可以包含自己为止 
				if(s=tr[v].to[i]){
					tr[s].g=j?tr[j].to[i]:1;
//					tr[s].d+=tr[tr[s].g].d;
					que[r++]=s;
				}
				else tr[v].to[i]=j?tr[j].to[i]:1;//补上一条边方便匹配 
			}
		}
	}
}ac;
inline void gao(){
	int n;cin>>n;
	ac.clear();
	for(int i=1;i<=n;++i){
		scanf("%s",str);
		int l=strlen(str);
		for(int j=0;j<l;++j)
			str[j]-='a';
		ac.Insert(l);
	}
	ac.build();
	scanf("%s",str);
	int m=strlen(str),res=0,rt=1;
	for(int i=0,j;i<m;++i){
		str[i]-='a';
		rt=ac.tr[rt].to[str[i]];
		if(ac.tr[rt].d){
			for(j=rt;;j=ac.tr[j].g){
				res+=ac.tr[j].d;
				ac.tr[j].d=0;
				if(j==1)break;
			}
		}
	}
	printf("%d\n",res);
}
int main(){
	int _;
	for(cin>>_;_--;)gao();
	return 0;
}


HDU3065

这道题生动的讲解了自动机的复杂度堆在哪

Code

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int M=50005;
#define debug(x) cout<<#x<<"="<<x<<endl
int n,allc;
struct node{
	int to[26],g,d;
}tr[M];
char P[1005][55],str[2000005];
int cnt[1005],que[M];
inline void clear(){
	for(int i=1;i<=allc;++i)
		for(int j=tr[i].g=tr[i].d=0;j<26;++j)
			tr[i].to[j]=0;
	allc=1;
}
inline void Insert(int id,int len){
	int rt=1;
	for(int i=0;i<len;++i){
		if(!tr[rt].to[P[id][i]])
			tr[rt].to[P[id][i]]=++allc;
		rt=tr[rt].to[P[id][i]];
	}
	tr[rt].d=id;
}
inline void build(){
	int l=0,r=0;
	for(que[r++]=1;l<r;){
		int u=que[l++];
		for(int i=0,j,s;i<26;++i){
			for(j=tr[u].g;j;j=tr[j].g)
				if(tr[j].to[i])break;
			if(s=tr[u].to[i]){
				tr[s].g=j?tr[j].to[i]:1;
				que[r++]=s;
			}
			else tr[u].to[i]=j?tr[j].to[i]:1;
		}
	}
}
inline bool check(char &s){
	return s>='A'&&s<='Z';
}
inline void gao(){
	clear();
	memset(cnt,0,sizeof(cnt));
	for(int i=1;i<=n;++i){
		scanf("%s",P[i]);
		int l=strlen(P[i]);
		for(int j=0;j<l;++j)
			P[i][j]-='A';
		Insert(i,l);
		for(int j=0;j<l;++j)
			P[i][j]+='A';
	}
	
	build();
	scanf("%s",str);
	
	int m=strlen(str),rt=1;
	for(int i=0;i<m;++i){
		if(!check(str[i])){rt=1;continue;}
		int c=str[i]-'A';
		rt=tr[rt].to[c];
		for(int j=rt;;j=tr[j].g){
			++cnt[tr[j].d];
			if(j==1)break;
		}
	}
	for(int i=1;i<=n;++i)
		if(cnt[i])
			printf("%s: %d\n",P[i],cnt[i]);
}
int main(){
	for(;cin>>n;)gao();
	return 0;
}

Tags:
Stats:
comments


Share:


Comments: