String HDU - 6096 多校#6 自动机

想总结的太多了。。。白天再来吧

#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
const int inf=0x3f3f3f3f;
const int maxn=2e6+71; 
const long long mod=998244353;
const int sigma=27;

int cnt[maxn];
struct automata{  
    int ch[maxn][sigma];  
    int val[maxn];		//是第几个串
    int f[maxn];  
	int len[maxn];		//字典树深度
    int sz;  
	int idx(char x){return x-'a';}
  
    int newnode(){  
        memset(ch[sz],0,sizeof(ch[sz]));  
        f[sz]=val[sz]=0; 
        return sz++;  
    }  
  
    void init(){  
		memset(val,0,sizeof val);
		sz=0;  
        newnode();  
    }  
  
    int insert(char *s,int v){   
        int u=0;  
        int _len=strlen(s);  

        for(int i=0;i<_len;i++){  
			int id=s[i]-'a';//s[i]-'a'; 
		   	//cout<<id<<endl;	
            if(!ch[u][id]){
				len[sz]=i+1;
				ch[u][id]=newnode();  
			}
            u=ch[u][id]; 
        }  
    	val[u]=v;
		//cout<<u<<" "<<v<<" "<<len[u]<<endl;
		return u;
	}  

    void build(){  
        queue<int>q;   
		q.push(0);    
        while(!q.empty()){  
            int u=q.front();q.pop();
			for(int i=0;i<sigma;i++){
				int v=ch[u][i];  
				if(!v)ch[u][i]=ch[f[u]][i];  
                else q.push(v);  
                if(u&&v)f[v]=ch[f[u]][i];  
			} 
        }  
    }  

	void query(char* s){
		int _len=strlen(s)/2+1;
		//cout<<_len<<endl;
		int u=0;
		for(int i=0;s[i];i++){
			//cout<<s[i]<<endl;
			u=ch[u][s[i]-'a'];
			int j=u;
			//if(!val[j])continue;	//非文本串结尾
			while(j){
				//cout<<j<<" "<<f[j]<<endl;	//bug!
				if(len[j]<=_len)cnt[j]++;
				j=f[j];	
			}
		}
		//cout<<"!!"<<endl;
	}
}ac; 

char s[maxn];
int pos[maxn];//第i个串的开头
char pre[maxn],suf[maxn];

int id[maxn];

int main(){
	int T,n,q;

	//ac.init();
	//char t1[10]="wq{qw";
	//char t2[10]="q{q";
	//ac.insert(t1,1);
	//ac.insert(t2,2);

	//ac.build();
	//for(int i=1;i<=8;i++){
	//	cout<<i<<" "<<ac.f[i]<<endl;
	//}
	//return 0;

	scanf("%d",&T);

	while(T--){
		memset(id,0,sizeof id);
		memset(pos,0,sizeof pos);
		memset(cnt,0,sizeof cnt);
		memset(ac.len,0,sizeof ac.len);

		ac.init();
		scanf("%d%d",&n,&q);
		
		for(int i=1;i<=n;i++){
			scanf("%s",s+pos[i]);int len=strlen(s+pos[i]);
			s[pos[i]+len]='{';
			for(int j=pos[i];j<pos[i]+len;j++){
				s[j+len+1]=s[j];
			}
			s[pos[i]+len+len+1]='\0';  
			pos[i+1]=pos[i]+strlen(s+pos[i])+1;
		}
		for(int i=1;i<=q;i++){
			scanf("%s",pre);
			scanf("%s",suf);
			int len1=strlen(suf);
			suf[len1]='{';int len=strlen(pre);
			for(int j=0;j<len;j++){
				suf[len1+j+1]=pre[j];
			}
			suf[len+len1+1]='\0';
			id[i]=ac.insert(suf,i);
		}
		//char t1[10]="wq#qw";
		//char t2[10]="q#q";
		//ac.insert(t1,1);
		//ac.insert(t2,2);

		ac.build();

		//for(int i=1;i<=8;i++){
		//	cout<<i<<" "<<ac.f[i]<<endl;
		//}
		//return 0;

		//ac.query(s+pos[1]);
		//printf("%d %d\n",cnt[1],cnt[2]);
	
		for(int i=1;i<=n;i++){
			ac.query(s+pos[i]);
		}
		for(int i=1;i<=q;i++){
			printf("%d\n",cnt[id[i]]);
		}

	}

}


posted @ 2017-08-22 02:30  Drenight  阅读(105)  评论(0编辑  收藏  举报