Description
Input
Output
Sample Input
6 8 25 0 24 14 8 6 18 0 10 20 24 0
7 14 17 8 7 0 17 0 5 8 25 0 24 0
4 8 25 0 24
4 7 0 17 0
4 17 0 8 25
Sample Output
2
1
0
1 2
【提示】
事实上样例给出的数据如果翻译成地球上的语言可以这样来看
2 3
izayoi sakuya
orihara izaya
izay
hara
raiz
HINT
【数据范围】
对于30%的数据,保证:
1<=N,M<=1000,喵星人的名字总长不超过4000,点名串的总长不超过2000。
对于100%的数据,保证:
1<=N<=20000,1<=M<=50000,喵星人的名字总长和点名串的总长分别不超过100000,保证喵星人的字符串中作为字符存在的数不超过10000。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 100000+5 14 #define maxm 50000+5 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int n,m,ans1[maxn],ans2[maxn]; 30 vector<int> a[20005],st[maxn],V,M; 31 map<int,int> next[maxn]; 32 bool v[maxn],mark[maxm]; 33 struct acm{ 34 int tot,ans; 35 int fail[maxn],q[maxn]; 36 acm(){ 37 tot=1; 38 for(int i=-1;i<=10000;i++) 39 next[0][i]=1; 40 fail[1]=0; 41 } 42 void insert(int pos){ 43 int now=1,L=read(); 44 for1(i,L){ 45 int x=read(); 46 if(!next[now][x])next[now][x]=++tot; 47 now=next[now][x]; 48 } 49 st[now].push_back(pos); 50 } 51 void build(){ 52 int head=0,tail=1; 53 q[0]=1; 54 while(head!=tail){ 55 int now=q[head];head++; 56 for(map<int,int>::iterator i=next[now].begin();i!=next[now].end();i++){ 57 int t=i->first,k=fail[now]; 58 while(!next[k][t])k=fail[k]; 59 fail[i->second]=next[k][t]; 60 q[tail++]=i->second; 61 } 62 } 63 } 64 void get(int pos,int x){ 65 for(int i=x;i;i=fail[i]) 66 if(!v[i]){ 67 v[i]=1;V.push_back(i); 68 for(int j=0;j<st[i].size();j++) 69 if(!mark[st[i][j]]){ 70 mark[st[i][j]]=1;M.push_back(st[i][j]); 71 ans1[st[i][j]]++; 72 ans2[pos]++; 73 } 74 } 75 else break; 76 } 77 void solve(int x){ 78 int now=1; 79 for0(i,a[x].size()){ 80 int t=a[x][i]; 81 while(!next[now][t])now=fail[now]; 82 now=next[now][t];get(x,now); 83 } 84 for0(i,V.size())v[V[i]]=0; 85 for0(i,M.size())mark[M[i]]=0; 86 V.clear();M.clear(); 87 } 88 }acm; 89 int main(){ 90 //freopen("input.txt","r",stdin); 91 //freopen("output.txt","w",stdout); 92 n=read();m=read(); 93 int L,x; 94 for1(i,n){ 95 L=read(),x; 96 while(L--)x=read(),a[i].push_back(x); 97 a[i].push_back(-1); 98 L=read(); 99 while(L--)x=read(),a[i].push_back(x); 100 } 101 for1(i,m) 102 acm.insert(i); 103 acm.build(); 104 for1(i,n) 105 acm.solve(i); 106 for1(i,m)printf("%d\n",ans1[i]); 107 for1(i,n){ 108 printf("%d",ans2[i]); 109 if(i!=n)printf(" "); 110 } 111 return 0; 112 }