[TJOI2013]单词 AC 自动机

Code:

#include<string>
#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void setIO(string a){
	freopen((a+".in").c_str(),"r",stdin);
}

#define maxn 2000004
vector<int>G[maxn];
char arr[maxn],total[maxn];
int tag[maxn],ans[maxn],map[maxn],cnt=-1;
struct Automaton{
	#define idx str[i]-'a' 
	#define root 0
	#define sigma 27
	int ch[maxn][sigma],last[maxn],fail[maxn],end[maxn];
	int nodes;
	int newnode(){ return ++nodes;}

	void insert(char str[],int id){
	    int n=strlen(str);
	    int pos=root;
	    for(int i=0;i<n;++i){
	    	if(!ch[pos][idx]) ch[pos][idx]=newnode();
	    	pos=ch[pos][idx];
	    }
	    G[pos].push_back(id);
	    end[pos]=1;
	    map[id]=pos;
    }

    queue<int>Q;
    void build(){
    	for(int i=0;i<sigma;++i) if(ch[root][i]) { Q.push(ch[root][i]),fail[ch[root][i]]=root; }
    	while(!Q.empty()){
    		int u=Q.front(); Q.pop();
    		for(int i=0;i<sigma;++i){
    			int r=ch[u][i];
    			if(!r) { ch[u][i]=ch[fail[u]][i]; continue; }
    			Q.push(r);
    			fail[r]=ch[fail[u]][i];
    			last[r]=end[fail[r]]? fail[r]: last[fail[r]];
    		}
    	}
    }

    bool vis[maxn];
    void print(int j){
    	while(j){
    		if(end[j]) tag[j]+=1;
    		j=last[j];
    	}
    }

    void query(char str[]){
    	int j=root;
    	for(int i=0;i<cnt;++i){
    		if(str[i]=='#') j=root;
    		else
    		{
    			j=ch[j][idx];
    			print(j);
    		}
    	}
    }   

}aho;
int main(){
	//setIO("input");
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;++i)  {
		scanf("%s",arr), aho.insert(arr,i);
		int cur_n=strlen(arr);
		for(int j=0;j<cur_n;++j)
			total[++cnt]=arr[j];
		total[++cnt]='#';
		++cnt;
	}
	aho.build();
    aho.query(total);
    for(int i=0;i<maxn;++i)
    	for(int j=0;j<G[i].size();++j) ans[G[i][j]]+=tag[i];
    for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
    return 0;
} 

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/9897755.html
今日推荐