记录编号 394843 评测结果 AAAAAAAAAA
题目名称 [SCOI 2012] 喵星球上的点名 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 1.601 s
提交时间 2017-04-14 18:04:45 内存使用 16.41 MiB
显示代码纯文本
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
const int N=4e5+10;
int n,m,top,len[N],par[N];
map<int,int> go[N];
int New(int L){len[++top]=L;return top;}
int extend(int last,int w){
	int p=last,np=New(len[p]+1);
	while (p&&!go[p][w]) go[p][w]=np,p=par[p];
	if (!p) par[np]=1;
	else{
		int q=go[p][w];
		if (len[q]==len[p]+1) par[np]=q;
		else{
			int nq=New(len[p]+1);
			go[nq]=go[q];
			par[nq]=par[q];
			par[np]=par[q]=nq;
			while (p&&go[p][w]==q) go[p][w]=nq,p=par[p];
		}
	}
	return np;
}
int vis[N],s[N],cnt[N];
void paint(int x,int C){
	if (!x||vis[x]==C) return;
	vis[x]=C;s[x]++;
	paint(par[x],C);
}
int sum(int x,int C){
	if (!x||vis[x]==C) return 0;
	vis[x]=C;
	return cnt[x]+sum(par[x],C);
}
const int M=5e4+10;
vector<int> a[M],b[M];
int main()
{
	freopen("wtfname.in","r",stdin);
	freopen("wtfname.out","w",stdout);
	scanf("%d%d",&n,&m);
	New(0);
	for (int id=1;id<=n;id++){
		int len,w;
		scanf("%d",&len);
		for (int i=1,last=1;i<=len;i++){
			scanf("%d",&w);
			a[id].push_back(w);
			last=extend(last,w);
		}
		scanf("%d",&len);
		for (int i=1,last=1;i<=len;i++){
			scanf("%d",&w);
			b[id].push_back(w);
			last=extend(last,w);
		}
	}
	for (int id=1;id<=n;id++){
		for (int i=0,last=1;i<a[id].size();i++){
			last=go[last][a[id][i]];
			paint(last,id);
		}
		for (int i=0,last=1;i<b[id].size();i++){
			last=go[last][b[id][i]];
			paint(last,id);
		}
	}
	for (int i=1;i<=m;i++){
		int len,w,last=1;
		scanf("%d",&len);
		for (int i=1;i<=len;i++){
			scanf("%d",&w);
			last=go[last][w];
		}
		printf("%d\n",s[last]);
		cnt[last]++;
	}
	for (int id=1;id<=n;id++){
		int ans=0;
		for (int i=0,last=1;i<a[id].size();i++){
			last=go[last][a[id][i]];
			ans+=sum(last,n+id);
		}
		for (int i=0,last=1;i<b[id].size();i++){
			last=go[last][b[id][i]];
			ans+=sum(last,n+id);
		}
		printf("%d ",ans);
	}
	puts("");
	return 0;
}