[Trie] Jzoj P5795 词典
题解
- 发现Σ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 }