听说这道题后缀数组暴力就能过,那我也就没写那些鬼畜的算法,将所有字符串粘合在一起,处理出来后缀数组然后暴力扫一遍即可。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
int sa[500000];
int rank[500000];
int s[500000];
int temp[500000];
int x[500000];
int y[500000];
int height[500000];
int sum[500000];
int num[500000];
int len=0;
void get_rank()
{
for(int i=1;i<=len;i++) sum[s[i]]++;
for(int i=1;i<=10001;i++) sum[i]+=sum[i-1];
for(int i=len;i>=1;i--) temp[sum[s[i]]--]=i;
int tot=0;
for(int i=1;i<=len;i++)
{
if(s[temp[i]]!=s[temp[i-1]] || i==1) tot++;
rank[temp[i]]=tot;
}
}
void ji_sort(int key[],int order[])
{
for(int i=0;i<=len;i++) sum[i]=0;
for(int i=1;i<=len;i++) sum[key[i]]++;
for(int i=1;i<=len;i++) sum[i]+=sum[i-1];
for(int i=len;i>=1;i--) temp[sum[key[order[i]]]--]=order[i];
for(int i=1;i<=len;i++) order[i]=temp[i];
}
void get_hou()
{
get_rank();
for(int j=1;j<=len;j<<=1)
{
for(int i=1;i<=len;i++)
{
x[i]=rank[i];
y[i]=i+j>len ? 0 : rank[i+j];
sa[i]=i;
}
ji_sort(y,sa);
ji_sort(x,sa);
int tot=0;
for(int i=1;i<=len;i++)
{
if(x[sa[i]]!=x[sa[i-1]] || y[sa[i]]!=y[sa[i-1]] || i==1)
tot++;
rank[sa[i]]=tot;
}
}
}
void get_height()
{
for(int i=1;i<=len;i++)
{
if(rank[i]==1) continue;
int k=max(0,height[rank[i-1]]-1);
while(s[i+k]==s[sa[rank[i]-1]+k]) k++;
height[rank[i]]=k;
}
}
int qi[100000];
int leng[100000];
int ci[100000];
bool pd[100000];
int time_clock[100000];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
len=0;
for(int i=1;i<=n;i++)
{
int t;
scanf("%d",&t);
for(int j=1;j<=t;j++)
{
scanf("%d",&s[++len]);
num[len]=i;
}
s[++len]=10001;
scanf("%d",&t);
for(int j=1;j<=t;j++)
{
scanf("%d",&s[++len]);
num[len]=i;
}
s[++len]=10001;
}
for(int i=1;i<=m;i++)
{
scanf("%d",&leng[i]);
qi[i]=len+1;
for(int j=1;j<=leng[i];j++) scanf("%d",&s[++len]);
s[++len]=10001;
}
get_hou();
get_height();
for(int i=1;i<=m;i++)
{
int t=rank[qi[i]];
int ans=0;
while(height[t]>=leng[i])
{
t--;
int mid=num[sa[t]];
if(mid)
{
if(time_clock[mid]!=i)
{
time_clock[mid]=i;
pd[mid]=false;
}
if(!pd[mid])
{
ci[mid]++;
pd[mid]=true;
ans++;
}
}
}
while(height[t+1]>=leng[i])
{
t++;
int mid=num[sa[t]];
if(mid)
{
if(time_clock[mid]!=i)
{
time_clock[mid]=i;
pd[mid]=false;
}
if(!pd[mid])
{
ci[mid]++;
pd[mid]=true;
ans++;
}
}
}
printf("%d\n",ans);
}
for(int i=1;i<n;i++) printf("%d ",ci[i]);
printf("%d",ci[n]);
return 0;
}