SAM 卡常求条
查看原帖
SAM 卡常求条
262620
hez_EX楼主2024/8/23 19:08

没错,又是我。

#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <vector>
#define ri register int
using namespace std;
int n,lnk[4000005],len[4000005],sz[4000005],lst,top;
int ehea[4000005],nhea[8000005],etop,ntop;
struct node
{
	int to,nxt,w;
}edge[4000005],nxt[8000005];
string t[200005];
char *s;
inline void adde(int f,int t,int w=0)
{
	edge[++etop]=(node){t,ehea[f],w};
	ehea[f]=etop;
}
inline void addn(int f,int t,int w=0)
{
	nxt[++ntop]=(node){t,nhea[f],w};
	nhea[f]=ntop;
}
inline int w2t(ri cur,int w)
{
	for(cur=nhea[cur];cur&&nxt[cur].w^w;cur=nxt[cur].nxt);
	return cur;
}
inline void ins(int c)
{
	int cur=++top;
	ri p=lst,tmp;len[lst=cur]=len[p]+1;
	while(p>=1&&!w2t(p,c)) addn(p,cur,c),p=lnk[p];
	if(p<1) return lnk[cur]=1,void();
	ri q=nxt[w2t(p,c)].to;
	if(len[q]==len[p]+1) return lnk[cur]=q,void();
	ri cpy=++top;
	for(ri i=nhea[q];i;i=nxt[i].nxt) addn(cpy,nxt[i].to,nxt[i].w);
	lnk[cpy]=lnk[q];len[cpy]=len[p]+1;lnk[q]=lnk[cur]=cpy;
	while(p>=1&&nxt[tmp=w2t(p,c)].to==q) nxt[tmp].to=cpy,p=lnk[p];
}
void dfs(int now)
{
	for(ri j=ehea[now];j;j=edge[j].nxt) dfs(edge[j].to),sz[now]+=sz[edge[j].to];
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	s=new char[2000005];
	cin>>n;lst=++top;
	for(ri i=1;i<=n;i++) cin>>t[i];cin>>s;
	for(ri i=0;s[i];i++) ins(s[i]-'a');
//	for(int i=0;i<=top;i++)
//		for(char j='a';j<='z';j++)
//			if(nxt[i].count(j)) printf("%d %d %c\n",i,nxt[i][j],j);
	for(ri i=1;i<=top;i++) adde(lnk[i],i);
//	cout<<"cp\n";
	for(ri cur=1;*s;s++) cur=nxt[w2t(cur,*s-'a')].to,sz[cur]=1/*,cout<<cur<<' ';puts("")*/;
	dfs(1);
	for(ri i=1;i<=n;i++)
	{
		ri cur=1,len=t[i].length();
		for(ri j=0;j<len;j++)
		{
			cur=nxt[w2t(cur,t[i][j]-'a')].to;
//			printf("%d ",cur);
			if(!cur) break;
		}
		if(cur) cout<<sz[cur]<<endl;
		else cout<<0<<endl;
	}
	return 0;
}
2024/8/23 19:08
加载中...