答案
2025-08-20 18:04:09
发布于:四川
1阅读
0回复
0点赞
#include<cstdio>
#include<cstring>
#include<iostream>
#define N 2020010
inline int read(){
int x=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch<='9'&&ch>='0') {x=x*10+ch-'0';ch=getchar();}
return x;
}
int n,m,a[N],n1,m1,bl[N],count[N],rank[N<<1],rank1[N],sa[N],height[N],k,tmp[N],visit[N],ans[N];
struct node{
int st,len;
}data[55000];
signed main(){
n1=read();m1=read();n=1;m=10000;
for (int i=1;i<=n1;++i){
int tmp=read();
for (int j=0;j<tmp;++j) a[n+j]=read(),bl[n+j]=i;n+=tmp;a[n++]=++m;
tmp=read();
for (int j=0;j<tmp;++j) a[n+j]=read(),bl[n+j]=i;n+=tmp;a[n++]=++m;
}int last=n-1;
for (int i=1;i<=m1;++i){
int tmp=read();
data[i].st=n;data[i].len=tmp;
for (int j=0;j<tmp;++j) a[n+j]=read();n+=tmp;a[n++]=++m;
}n-=1;
for (int i=1;i<=n;++i) count[a[i]]=1;
for (int i=1;i<=m;++i) count[i]+=count[i-1];
for (int i=1;i<=n;++i) rank[i]=count[a[i]];
k=0;count[0]=0;
for (int p=1;k!=n;p<<=1,m=k){
for (int i=1;i<=m;++i) count[i]=0;
for (int i=1;i<=n;++i) count[rank[i+p]]++;
for (int i=1;i<=m;++i) count[i]+=count[i-1];
for (int i=n;i>=1;--i) tmp[count[rank[i+p]]--]=i;
for (int i=1;i<=m;++i) count[i]=0;
for (int i=1;i<=n;++i) count[rank[i]]++;
for (int i=1;i<=m;++i) count[i]+=count[i-1];
for (int i=n;i>=1;--i) sa[count[rank[tmp[i]]]--]=tmp[i];
memcpy(rank1,rank,sizeof(rank)>>1);
rank[sa[1]]=k=1;
for (int i=2;i<=n;++i){
if (rank1[sa[i]]!=rank1[sa[i-1]]||rank1[sa[i]+p]!=rank1[sa[i-1]+p]) ++k;
rank[sa[i]]=k;
}
}
k=0;
for (int i=1;i<=n;++i){
if (rank[i]==1) continue;
k=k==0?0:k-1;
while (a[i+k]==a[sa[rank[i]-1]+k]) ++k;
height[rank[i]]=k;
}
for (int i=1;i<=m1;++i){
int l=rank[data[i].st],r=rank[data[i].st]+1;
while (height[l]>=data[i].len) --l;
while (height[r]>=data[i].len) ++r;--r;
int tmp=0;
for (int j=l;j<=r;++j){
if (sa[j]>last) continue;
if (visit[bl[sa[j]]]==i) continue;
tmp++;ans[bl[sa[j]]]++;visit[bl[sa[j]]]=i;
}
printf("%d\n",tmp);
}
for (int i=1;i<=n1;++i) printf("%d ",ans[i]);
return 0;
}
这里空空如也
有帮助,赞一个