今天无聊神游发现了Trie的裸题:大LCP,于是就去学了学,找了半个小时,才发现一篇较好的博客,于是瞎搞了一小时就会了。
JZOJ 3126【GDKOI2013选拔】大LCP
Description
LCP就是传说中的最长公共前缀,至于为什么要加上一个大字,那是因为…你会知道的。
首先,求LCP就要有字符串。既然那么需要它们,那就给出n个字符串好了。
于是你需要回答询问大LCP,询问给出一个k,你需要求出前k个字符串中两两的LCP最大值是多少,这就是传说中的大LCP。
Input
第一行一个整数N,Q,分别表示字符串个数和询问次数。
接下来N行,每行一个字符串。
再Q行,每行一个正整数k。
Output
Q行,依次分别表示对Q个询问的答案。
Sample Input
3 3
a
b
ab
1
2
3
Sample Output
0
0
1
Data Constraint
对于30%的数据,字符串总长度不超过10^4,1<=N<=10^3,1<=Q<=10.
接下来30%的数据,字符串总长度不超过10^4,1<=N<=10^3,1<=Q<=1000.
对于100%的数据,字符串总长度不超过10^6,1<=N,Q<=10^5.
直接上代码:
var
trie:array[1..1000000,'a'..'z'] of longint;
a:array[0..100000] of longint;
i,j,sum,now,tn,n,q,x:longint;
s:string;
begin
readln(n,q);
tn:=1;
for i:=1 to n do
begin
readln(s);
now:=1; sum:=0; a[i]:=a[i-1];
for j:=1 to length(s) do
if trie[now,s[j]]=0 then
begin
inc(tn);
fillchar(trie[tn],sizeof(trie[tn]),0);
trie[now,s[j]]:=tn;
now:=tn;
end else
begin
inc(sum);
now:=trie[now,s[j]];
end;
if sum>a[i] then
a[i]:=sum;
end;
for i:=1 to q do
begin
readln(x);
writeln(a[x]);
end;
end.