【BZOJ1174】: [Balkan2007]Toponyms

→原题←

↑这样子我就不复制题面啦~

就是一题很裸的字典树而已,不过空间卡的很死,直接开个数组 tr[N][52] 什么之类的一定会RE的(惨痛的教训)

当字典树空间不够而时间限制又比较宽松时,我们可以像平时前向星存图那样动态地为字典树开点(哪一个字典树不是动态开点。。

总之把数组大小开到最极限的 5e6 可以勉强通过此题。

我读入时使用了 getline 这样子会很慢啦,可以直接巧妙地一个个 getchar 的(好在BZOJ上限制的是10秒)

代码~

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 
 7 #define For(i,a,b) for(register int i=a;i<=b;++i)
 8 #define Re register 
 9 
10 using namespace std;
11 const int N=5e6+10;
12 int head[N],nxt[N],key[N],v[N],cnt[N],ct=1;
13 int ans=0,n,BH=1;
14 string s;
15 
16 void Ins(){
17     int len=s.size();
18     int Px=0,dep=0,now=1;
19     while(Px<len){
20         bool hK=0;
21         for(Re int i=head[now];i;i=nxt[i]){
22             int vv=v[i];
23             if(key[vv]==s[Px]){
24                 now=vv; hK=1; break;
25             }
26         }
27         if(!hK){
28             ct++;
29             nxt[ct]=head[now]; head[now]=ct; v[ct]=++BH;
30             now=BH;
31             key[now]=s[Px];
32         }
33         cnt[now]++;
34         dep++;
35         ans=max(ans,dep*cnt[now]);
36         Px++;
37     }
38 }
39 
40 int main(){
41     cin>>n;
42     char c=getchar();
43     For(i,1,n){
44         getline(cin,s);
45         Ins();
46     }
47     cout<<ans<<endl;
48     return 0;
49 }

猜你喜欢

转载自www.cnblogs.com/HLAUV/p/9920435.html