链接
https://www.luogu.org/problem/show?pid=2922
大意
给定
个已加密元素,
个钥匙
(感性理解一下。。。)
问每把钥匙串与加密串的最长前缀
思路
用
表示中间字符的出现次数,
表示当前串的出现次数
做一遍
即可
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int trie[500001][2],tot,n,ans,end[500001],cnt[500001],sum[500001],m;
bool a[500001];
inline void insert(register bool a[],register int len)
{
int p=0;
for(register int k=1;k<=len;k++)
{
if(!trie[p][a[k]]) trie[p][a[k]]=++tot;
p=trie[p][a[k]];
sum[p]++;//字符出现次数
}
end[p]++;//该串出现次数
return;
}
inline void search(register bool a[],register int len)
{
int p=0,ans=0;
for(register int k=1;k<=len;k++)
{
if(!trie[p][a[k]])
{
printf("%d\n",ans);//无法拓展直接输出
return;
}
p=trie[p][a[k]];
ans+=end[p];//加上子串
}
printf("%d\n",ans-end[p]+sum[p]);//能完全找到,减去之前所有的end加上sum
return;
}
signed main()
{
scanf("%d%d",&n,&m);
for(register int i=1,t;i<=n;i++)
{
scanf("%d",&t);
for(register int j=1;j<=t;j++) scanf("%d",a+j);
insert(a,t);
}
for(register int i=1,t;i<=m;i++)
{
scanf("%d",&t);
for(register int j=1;j<=t;j++) scanf("%d",a+j);
search(a,t);
}
}