前缀(字典树)

  描述:给定N个字符串,求这些字符串的最长公共前缀长度与字符串的个数的乘积的最大值。

   范围:1<=N<=1000000    每个字符串长度小于20000

   样例:

  7

  Jora de Sus
  Orhei
  Jora de Mijloc
  Joreni
  Jora de Jos
  Japca
  Orhejul Vechi

  

  方法一:裸的字典树

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 struct letter{
 5     char d;//节点存的字符
 6     int son,bro;//左孩子和右兄弟,都是节点编号
 7     int cnt;//此节点的孩子个数
 8 };
 9
10 char line[30000];
11 int N,best=0,gs=0;
12 letter tr[10000001];
13
14 void insert(char s[]){
15     int len=strlen(s);//字符串长度,也是字符串在树中的深度
16     int now=0;//当前节点
17
18     for(int i=0;i<len;i++){//i表示深度,深度为0的是root,并不是某字符
19         tr[now].cnt++;
20
21         if(tr[now].cnt*i>best)//每一个节点都尝试更新答案
22             best=tr[now].cnt*i;
23
24         if(tr[now].son==0){//这个节点没有左孩子
25             tr[++gs].d=s[i];//插入点
26             tr[now].son=gs;//让gs为now的左孩子
27             now=gs;//更行当前节点
28         }
29         else{
30             now=tr[now].son;
31             while(tr[now].d!=s[i]&&tr[now].bro>0){//找到合适的节点插入
32                 now=tr[now].bro;
33             }
34             if(tr[now].d!=s[i]){
35                 tr[++gs].d=s[i];
36                 tr[now].bro=gs;
37                 now=gs;
38             }
39
40         }
41     }
42     tr[now].cnt++;
43
44     if(tr[now].cnt*len>best){//这个更新容易漏掉
45         best=tr[now].cnt*len;
46     }
47
48
49 }
50
51 int main(){
52     scanf("%d",&N);
53     for(int i=1;i<=N;i++){
54         gets(line);
55         insert(line);
56     }
57     cout<<best;
58     return 0;
59 }
时间: 2024-08-09 19:53:44

前缀(字典树)的相关文章

HDU 1251 统计难题 (字典树)(查询是否为前缀)

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submission(s): 37626    Accepted Submission(s): 13858 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的

常用算法之Trie【字典树,前缀树】

Trie中文名又叫做字典树,前缀树等,因为其结构独有的特点,经常被用来统计,排序,和保存大量的字符串,经常见于搜索提示,输入法文字关联等,当输入一个值,可以自动搜索出可能的选择.当没有完全匹配的结果时,可以返回前缀最为相似的可能. 其实腾讯的面试题有一个:如何匹配出拼写单词的正确拼写.其实用匹配树非常合适. 基本性质: 1.根节点不含有字符,其余各节点有且只有一个字符. 2.根节点到某一节点中经过的节点存储的值连接起来就是对应的字符串. 3.每一个节点所有的子节点的值都不应该相同. 借用一下维基

hdu1251 字典树的应用(查询公共前缀)

http://acm.hdu.edu.cn/showproblem.php?pid=1251 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每

简单的字典树(前缀树)

写这个树,主要是为了完成这道题目.http://hihocoder.com/problemset/problem/1014 代码如下,注释有比较详细的解释 1 #include <iostream> 2 #include <string> 3 #include <typeinfo> 4 #include <vector> 5 using namespace std; 6 7 /*****************************************

Hash树(散列树)和Trie树(字典树、前缀树)

1.Hash树 理想的情况是希望不经过任何比较,一次存取便能得到所查的记录, 那就必须在记的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和一个唯一的存储位置相对应.因而在查找时,只要根据这个对应关系f找到 给定值K的像f(K).由此,不需要进行比较便可直接取得所查记录.在此,我们称这个对应关系为哈希(Hash)函数,按这个思想建立的表为哈希表. 在哈希表中对于不同的关键字可能得到同一哈希地址,这种现象称做冲突.在一般情况下,冲突只能尽可能地减少,而不能完全避免.因为哈希函数是从

9-11-Trie树/字典树/前缀树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第9章  查找 - Trie树/字典树/前缀树(键树) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.Scanf.c        相关测试数据

HDU 1671 (字典树统计是否有前缀)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1671 Problem Description Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogue listed these numbers: 1. Emergenc

字典树练习(一)hihocoder 1014(求相同前缀的数目)

题目链接: http://hihocoder.com/problemset/problem/1014 题意: 给定n个单词,然后我们构成一个字典树,然后再给你m个串,求有多少个单词是以这个串为前缀的. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100010;

HDU 5687 Problem C ( 字典树前缀增删查 )

题意 : 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 1.insert : 往神奇字典中插入一个单词 2.delete: 在神奇字典中删除所有前缀等于给定字符串的单词 3.search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串 分析 : 利用字典树,插入操作时对于每一个节点的标记权值+1,代表此前缀+1,然后删除操作的时候尤为要注意的就是对于给出的前缀,不能在字典树上将权值置为0,因为如果现在假设已经插入了 abc.ab 现在要求 delete abc 则不能将 a