AC自动机

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring >
#include<algorithm>
using namespace std;

struct point 
{
	int son[30];
	int vis;
	int viv;
	int fa;
	int fail;
}   ;
point tree[1100000];
point tiee[1000000];
int fault[1000000];
int take[1000000];

int low[1010100];
int num=0;
int len;
void getdown(int fat,string x,int pla)
{
	if(pla<=len)


      {
		int a=x[pla-1]-'a'+1;
    	int yy=0;
  
	 if(tree[fat].son[a]==0) {
	 	num++;
	 	tree[fat].son[a]=num;
	 	tree[tree[fat].son[a]].vis++;
	 	tree[tree[fat].son[a]].viv=a;
	 	tree[tree[fat].son[a]].fa=fat;
	 	getdown(num,x,pla+1);
	           }  
	else   {
		tree[tree[fat].son[a]].vis++;
		getdown(tree[fat].son[a],x,pla+1);
	       }
	   }
}
int num2=0;
int paa;
int h=0;struct pu
{
	int  a,b;
	int nxt;
}   lenn[1000000];
int fir[1000000];
void  add(int a,int b)
{
	if(a==take[3]) cout<<b<<"aatty";
	h++;
	lenn[h].a=a;
	lenn[h].b=b;
	lenn[h].nxt=fir[a];
	fir[a]=h;
	
}
void get(int fat,string x,int pla)
{

    
    if(pla==len+1) take[paa]=fat;
	if(pla<=len)
	{
	
	int a=x[pla-1]-'a'+1;
	if(tiee[fat].son[a]==0){
		                   num2++;
		                   tiee[fat].son[a]=num2;
		                   tiee[num2].viv=a;
		                //   tiee[num2].vis++;
		                   tiee[num2].fa=fat;
		                   if(fat==0)  tiee[num2].fail=0;
				           else {
                            int po=tiee[fat].fail ;
                            
				           	while(tiee[po].son[a]==0&&po!=0){
				           		po=tiee[po].fail;
							                         }
						  if(po!=0||(tiee[po].son[a]==0))    {
						  	
						      tiee[num2].fail=po;
						      if(po!=0) add(po,num2);
							                                         }  
						  else   if(po==0&&tiee[po].son[a]!=0){
						  	  tiee[num2].fail=tiee[po].son[a];
						         add(tiee[po].son[a],num2);                                      }
							    }
					       get(num2,x,pla+1);
	                       }
	else                      {
		 
		get(tiee[fat].son[a],x,pla+1);
	                           } 
    }
}



void pla(int x)
{      
	  if(tiee[tree[x].fa].son[tree[x].viv]!=0){
	   // if(x==3) cout<<tiee[1].vis<<"cd"<<tiee[tree[x].fa].son[tree[x].viv]<<"rt"<<tree[x].viv<<"uy";
	  	tiee[tiee[tree[x].fa].son[tree[x].viv]].vis+=tree[x].vis;
	  	for(int i=1;i<=26;i++)
  {
  	if(tree[x].son[i]!=0){
  		tree[tree[x].son[i]].fa=tiee[tree[x].fa].son[tree[x].viv];
	                     }
  }      
    // if(x==2) cout<<tiee[tiee[tree[x].fa].son[tree[x].viv]].fail<<"you arre     rrr";                                    
	                                          }
    else if(tiee[tree[x].fa].son[tree[x].viv]==0){
   // 	if(x==3) cout<<tiee[1].vis<<"cd"<<tiee[tree[x].fa].son[tree[x].viv]<<"rt"<<tree[x].viv<<"uy";
    	num2++;
    	tiee[tree[x].fa].son[tree[x].viv]=num2;
    	tiee[tiee[tree[x].fa].son[tree[x].viv]].vis=tree[x].vis;
	    int po=tiee[tree[x].fa].fail ;
                            
     	while(tiee[po].son[tree[x].viv]==0&&po!=0){
				           		po=tiee[po].fail;
		                                         }
			//	if(x==3) cout<<tiee[1].vis<<"cd"<<tiee[tree[x].fa].son[tree[x].viv]<<"rt"<<tree[x].viv<<"uy";
        if(po!=0||(po==0&&tiee[po].son[tree[x].viv]==0))    			       {
		                      tiee[num2].fail=po;
						      if(po!=0) add(po,num2);                           }
	    else   if(po==0&&tiee[po].son[tree[x].viv]!=0)   {
	                            tiee[num2].fail=tiee[po].son[tree[x].viv];
								add(tiee[po].son[tree[x].viv],num2);	
		                                                 }
						  	for(int i=1;i<=26;i++)
  {
  	if(tree[x].son[i]!=0){
  		tree[tree[x].son[i]].fa=tiee[tree[x].fa].son[tree[x].viv];
	             }
  }                   	      
							                      }
	
   
}
int dfsaa[1000000];
int sum[1000000];
int numdfs=0;
void ad(int x,int b)
{
	while(x<=numdfs)
	{
		sum[x]+=b;
		x+=low[x];
	}
}
int  query(int x)
{
	int sm=0;
	while(x>=1)
	{
		sm+=sum[x];
	    x-=low[x];
	}
	return sm;
}
int dfs(int x)
{
	int st=take[x];
	numdfs++;
	ad(numdfs,tiee[st].vis);
	dfsaa[st]++;	for(int i=fir[st];i!=-1;i=lenn[i].nxt)
	{
     //  if(x==5)cout<<lenn[i].b<<"aae";
		if(dfsaa[lenn[i].b]==0){
	           numdfs++;
			   ad(numdfs,tiee[lenn[i].b].vis);
	          dfsaa[lenn[i].b]++;		   		
		              }
	}
//	if(x==3) cout<<numdfs<<"aass";
   // cout<<numdfs<<"you are silly";
	return query(numdfs);
}
int main()
{
	int n,m;
	scanf("%d", &n);
	for(int i=1;i<=n;i++)
	{
		string x;
	    cin>>x;
	    len=x.size();
		getdown(0,x,1);
	}

	cin>>m;
	memset(fir,-1,sizeof(fir));
	for(int i=1;i<=m;i++)
	{
		string p;
		cin>>p;
		paa=i;
	    len=p.size();
		get(0,p,1);
	}

	for(int i=1;i<=num;i++)
	{
		pla(i);	//cout<<num2<<"silly ";
	//	cout<<tiee[2].vis<<" as";
	}
	
	for(int i=1;i<=1000000;i++)
	low[i]=i&-i;
//cout<<"silly you are";
    
   //cout<<dfs(3)<<"aa";
	for(int i=1;i<=m;i++)
	{
		numdfs=0;
		memset(sum,0,sizeof(sum));
		int anssss=dfs(i);
	 //if(i==4) cout<<dfs(4)<<"aas";
		printf("%d\n",anssss);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值