记录编号 490077 评测结果 TTTAAAAAAA
题目名称 [SCOI 2012] 喵星球上的点名 最终得分 70
用户昵称 GravatarShirry 是否通过 未通过
代码语言 C++ 运行时间 5.962 s
提交时间 2018-03-07 10:22:17 内存使用 42.25 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000010;
struct poi{int len,beg;}q[maxn];
int x[maxn],y[maxn],s[maxn],c[maxn],sa[maxn],height[maxn];
int n,m,len,vis[maxn],ans[maxn],belong[maxn];
void get_sa(){
	int *rnk=x,*tp=y,knd=200000;
	for(int i=1;i<=len;i++)rnk[i]=tp[i]=s[i],c[rnk[i]]++;
	for(int i=1;i<=knd;i++)c[i]+=c[i-1];
	for(int i=len;i>=1;i--)sa[c[rnk[i]]--]=i;
	for(int j=1;j<=len;j<<=1){
		int p=0;
		for(int i=len-j+1;i<=len;i++)tp[++p]=i;
		for(int i=1;i<=len;i++)if(sa[i]>j)tp[++p]=sa[i]-j;
		for(int i=0;i<=knd;i++)c[i]=0;
		for(int i=1;i<=len;i++)c[rnk[tp[i]]]++;
		for(int i=1;i<=knd;i++)c[i]+=c[i-1];
		for(int i=len;i>=1;i--)sa[c[rnk[tp[i]]]--]=tp[i];
		swap(rnk,tp);p=1,rnk[sa[1]]=1;
		for(int i=2;i<=len;i++){
			int O1=sa[i]+j>len?-1:tp[sa[i]+j];
			int O2=sa[i-1]+j>len?-1:tp[sa[i-1]+j];
			rnk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&O1==O2)?p:++p;
		}
		knd=p;
		if(knd>=len)break;
	}
}
void get_height(){
	int p=0,j;
	for(int i=1;i<=len;i++)x[sa[i]]=i;
	for(int i=1;i<=len;i++){
		if(p)p--;
		j=sa[x[i]-1];
		while(s[i+p]==s[j+p])p++;
		height[x[i]]=p;
	}
}
int main(){
	freopen("wtfname.in","r",stdin);
	freopen("wtfname.out","w",stdout);
	int op,fg=11000;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&op);
		for(int j=1;j<=op;j++)belong[++len]=i,scanf("%d",&s[len]);
		s[++len]=++fg;
		scanf("%d",&op);
		for(int j=1;j<=op;j++)belong[++len]=i,scanf("%d",&s[len]);
		s[++len]=++fg;
	}
	for(int i=1;i<=m;i++){
		scanf("%d",&q[i].len);
		q[i].beg=len;
		for(int j=1;j<=q[i].len;j++)scanf("%d",&s[++len]);
		s[++len]=++fg;
	}
	get_sa();
	get_height();
	for(int i=1;i<=m;i++){
		int L,R;
		L=R=x[q[i].beg+1];
		while(height[L]>=q[i].len)L--;
		while(height[R]>=q[i].len)R++;
		R--;int sum=0;
		for(int j=L;j<=R;j++){
			if(belong[sa[j]]){
				if(vis[belong[sa[j]]]!=i){
					vis[belong[sa[j]]]=i;
					sum++;
					ans[belong[sa[j]]]++;
				}
			}
		}
		printf("%d\n",sum);
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	return 0;
}