锰锌刚学ACAM求调教
查看原帖
锰锌刚学ACAM求调教
1249322
Elaina_0楼主2024/9/6 19:49

感谢dalao

record

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define rd read()
#define mkp make_pair
#define psb push_back
#define Elaina 0
#define mst(a,b) memset((a),(b),sizeof(a))
#define random(a,b) (1ll*rand()*rand()*rand()%((b)-(a)+1)+(a))
inline ll read(){
	ll f=1,x=0;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f=(ch=='-'?-1:1);
	for(;isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
	return f*x;
}
const int mod=1e9+7;
const int N=2e6+100;
const int inf=0x7fffffff;

int n,m;
char s[N];

namespace AC{
	int cnt,num;
	int ind[N],vis[N],rev[N];
	struct ciallo{
		int son[27],flg,fail,ans;
	}tr[N];
	
	void insert(char *s){
		int x=1,len=strlen(s);
		for(int i=0;i<len;i++){
			int ch=s[i]-'a';
			if(!tr[x].son[ch]) tr[x].son[ch]=++cnt;
			x=tr[x].son[ch];
		}
		if(!tr[x].flg) tr[x].flg=++num;
		rev[num]=tr[x].flg;
	}
	
	void getFail(){
		queue<int> q;
      
//这里应该是没区别的吧
//		for(int i=0;i<26;i++)
//			if(tr[0].son[i])
//				q.push(tr[0].son[i]);
		
		for (int i = 0; i < 26; i++) tr[0].son[i] = 1;
  		q.push(1);
  		tr[1].fail = 0;
				
		while(!q.empty()){
			int x=q.front();
			q.pop();
			for(int i=0;i<26;i++){
				int ch=tr[x].son[i],fail=tr[x].fail;
				if(!ch){
					tr[x].son[i]=tr[fail].son[i];
				}else{
					tr[ch].fail=tr[fail].son[i];
					ind[tr[fail].son[i]]++;
					q.push(ch);
				}
			}
		}
	}
	
	void query(char *s){
		int x=1,len=strlen(s);
		for(int i=0;i<len;i++){
			int ch=s[i]-'a';
			x=tr[x].son[ch];
			tr[x].ans++;
		}
	}
	
	void topu(){
		queue<int> q;
		for(int i=1;i<=cnt;i++){
			if(!ind[i]){
				q.push(i);
			}
		}
		
		while(!q.empty()){
			int x=q.front();
			q.pop();
			vis[tr[x].flg]=tr[x].ans;
			int fail=tr[x].fail;
			tr[fail].ans+=tr[x].ans;
			if(!(--ind[fail])) q.push(fail);
		}
	}
}
using namespace AC;

signed main(){
	cnt=1;
	
	n=rd;
	for(int i=1;i<=n;i++){
		scanf("%s",s);
		insert(s);
	}
	
	getFail();
	scanf("%s",s);
	query(s);
	topu();
	
	int ans=0;
	for(int i=1;i<=n;i++){
		cout<<vis[rev[i]]<<endl;
//		ans=max(ans,vis[rev[i]]);
	}
//	printf("%lld\n",ans);
	return Elaina;
} 
2024/9/6 19:49
加载中...