题面
时间限制:3s,空间限制:512MB
【题目描述】
给你一个字符串集合,请从中找出一些字符串,使得找出来的这些字符串的最长公共前缀与这些字符串数的总个数的乘积最大化,并输出这个最大值
【输入】
输入文件第一行给出字符串个数
n
(
1
≤
n
≤
1000000
)
n(1≤n≤1000000)
n(1≤n≤1000000),下面n行描述这n个字符串,每个字符串长度不超过
20000
20000
20000;输入文件在
10
M
B
10MB
10MB以内。
【输出】
输出文件一行一个数,代表最大化的结果
【样例输入】
7
Jora de Sus
Orhei
Jora de Mijloc
Joreni
Jora de Jos
Japca
Orheiul Vechi
【样例输出】
24
算法分析
本题卡空间,如果使用二维数组存储Trie字典树,会超空间。
这里使用单链表存储字典树,例如存储以下字典树:
ada
bx
cf
参考程序
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define For(i,a,b) for(register int i=a;i<=b;++i)
#define Re register
using namespace std;
const int N=2e7+10;
int head[N],nxt[N],key[N],v[N],cnt[N],ct=1;
int ans=0,n,BH=1;
string s;
void Ins(){
int len=s.size();
int Px=0,dep=0,now=1;
while(Px<len){
bool hK=0;
for(Re int i=head[now];i;i=nxt[i]){
int vv=v[i];
if(key[vv]==s[Px]){
now=vv; hK=1; break;
}
}
if(!hK){
ct++;
nxt[ct]=head[now]; head[now]=ct; v[ct]=++BH;
now=BH;
key[now]=s[Px];
}
cnt[now]++;
dep++;
ans=max(ans,dep*cnt[now]);
Px++;
}
}
int main(){
cin>>n;
char c=getchar();
For(i,1,n){
getline(cin,s);
Ins();
}
cout<<ans<<endl;
return 0;
}