[Trie] Jzoj P5795 词典

Description
 
Input
第一行两个数n,m,表示有n个字符串,m个询问。
接下来n行,每行一个字符串Ti 。
再接下来m行,每行一个字符串Si 。
Output
对于每个询问,输出一个ansi表示答案。
 
Sample Input
3 2
abcabc
aabc
abbc
aa
ba  
Sample Output
1
3 
 
Data Constraint

 

 

题解

  • 发现Σlen[t[i]]<=5*10^6,显然可以建trie
  • 考虑如何找最长全0串
  • 分三种情况:
  • ①没有走过的点,当前i前面的都没有包含它的,为i-1
  • ②走过的点,再上次走到当前层的是第i个字符串,然后走到这个时为i-1-w[p]
  • ③最后的w[p]到n

代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 int n,m,tot=1,trie[5000001][3],w[5000001],k[5000001];
 6 char str[5000001];
 7 void insert(int x)
 8 {
 9     int len=strlen(str+1),p=1;
10     for (int i=1;i<=len;i++)
11     {
12         int ch=str[i]-'a';
13         if (!trie[p][ch]) p=trie[p][ch]=++tot,k[p]=x-1;
14         else p=trie[p][ch],k[p]=max(k[p],x-1-w[p]);
15         w[p]=x;
16     }
17 }
18 int search()
19 {
20     int len=strlen(str+1),p=1;
21     for (int i=1;i<=len;i++)
22     {
23         int ch=str[i]-'a';
24         if (trie[p][ch]==0) return n;
25         p=trie[p][ch];
26     }
27     return max(k[p],n-w[p]);
28 }
29 int main()
30 {
31     freopen("word.in","r",stdin);
32     freopen("word.out","w",stdout);
33     scanf("%d%d",&n,&m);
34     for (int i=1;i<=n;i++) scanf("%s",str+1),insert(i);
35     for (int i=1;i<=m;i++) scanf("%s",str+1),printf("%d\n",search());
36     return 0;
37 }

 

转载于:https://www.cnblogs.com/Comfortable/p/9457057.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值