Hyper Prefix Sets

uva11488:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2483

题意:给你n个串,对于一个前缀,如果出现k次,就会得到前缀的长度*k,现在让你求长度*k的最大值。

题解:用trie树来搞。把每个串插入到trie中,记录每个子串出现的次数以及长度,trie树很容易实现,然后插完之后,把每个节点遍历一遍,求最大的len*sum,输出即可。

 1 #include<cstring>
 2 #include<vector>
 3 #include<cstdio>
 4 using namespace std;
 5 const int maxnode = 4000 * 1000 + 10;
 6 const int sigma_size = 26;
 7 char word[10002];
 8 int n,m;
 9 int sz;
10 struct Trie {
11   int head[maxnode]; // head[i]为第i个结点的左儿子编号
12   int next[maxnode]; // next[i]为第i个结点的右兄弟编号
13   char ch[maxnode];  // ch[i]为第i个结点上的字符
14   int sum[maxnode];
15   int len[maxnode];
16   void clear() {
17     sz = 1;
18     head[0] = next[0] = 0;
19     memset(len,0,sizeof(len));
20     memset(sum,0,sizeof(sum));
21     }
22   void insert(const char *s,int form ,int to) {
23     int u = 0, v;
24     for(int i = form; i <to; i++) {
25       bool found = false;
26       for(v = head[u]; v != 0; v = next[v])
27         if(ch[v] == s[i]) { // 找到了
28           found = true;
29           break;
30         }
31       if(!found) {
32         v = sz++; // 新建结点
33         ch[v] = s[i];
34         next[v] = head[u];
35         head[u] = v; // 插入到链表的首部
36         head[v] = 0;
37       }
38       u = v;
39       sum[u]++;
40       len[u]=i+1;
41     }
42 }
43 }trie;
44 int cas;
45 int main() {
46       scanf("%d",&cas);
47   while(cas--) {
48        trie.clear();
49        scanf("%d",&n);
50        for(int i=1;i<=n;i++){
51         scanf("%s", word);
52            m=strlen(word);
53          trie.insert(word,0,m);
54        }
55        int ans=0;
56        for(int i=1;i<sz;i++){
57           ans=max(ans,trie.len[i]*trie.sum[i]);
58        }
59       printf("%d\n",ans);
60   }
61     return 0;
62 }
View Code

 

posted on 2014-08-14 13:35  天依蓝  阅读(125)  评论(0编辑  收藏  举报

导航