这道题也是卡了挺久的。

给出一个字符串比较的算法,有n个字符串两两比较一次,问一共会有多少次比较。

因为节点会很多,所以Tire树采用了左儿子右兄弟的表示法来节省空间。

假设两个不相等的字符串的最长公共前缀的长度为i,那么比较次数应该是2i+1。

如果两个字符串相等,比较次数则是2i+2.

可以像大白书上一样先构建好Tire树,然后DFS统计答案。

 #include <cstdio>
#include <cstring> const int maxnode = * + ; struct Tire
{
int sz;
int son[maxnode], bro[maxnode], tot[maxnode];
char ch[maxnode];
long long ans;
void clear() { sz = ; son[] = bro[] = tot[] = ; } void insert(char* s)
{
int u = , v, n = strlen(s);
tot[]++;
for(int i = ; i <= n; i++)
{
bool found = false;
for(v = son[u]; v; v = bro[v])
if(ch[v] == s[i]) { found = true; break; }
if(!found)
{
v = sz++;
son[v] = ;
bro[v] = son[u];
son[u] = v;
tot[v] = ;
ch[v] = s[i];
}
u = v;
tot[u]++;
}
} void dfs(int d, int u)
{
if(son[u] == ) { ans += tot[u] * (tot[u]-) * d; return; }//叶节点
long long sum = ;
for(int v = son[u]; v; v = bro[v])
sum += tot[v] * (tot[u] - tot[v]);
ans += sum / * (d * + );
for(int v = son[u]; v; v = bro[v]) dfs(d+, v);
} long long count()
{
ans = ;
dfs(, );
return ans;
}
}tire; const int maxl = + ;
char s[maxl]; int main()
{
//freopen("in.txt", "r", stdin); int n, kase = ;
while(scanf("%d", &n) == && n)
{
tire.clear();
for(int i = ; i < n; i++) { scanf("%s", s); tire.insert(s); }
printf("Case %d: %lld\n", ++kase, tire.count());
} return ;
}

代码君

也可以边插入字符串边统计,代码更短,而且速度也更快。这种做法是从某位菊苣的博客中看到的。

 #include <cstdio>
#include <cstring> const int maxnode = * + ; long long ans; struct Tire
{
int son[maxnode], bro[maxnode], tot[maxnode];
char ch[maxnode];
int sz;
void clear() { sz = ; son[] = bro[] = tot[] = ; } void insert(char* s)
{
int u = , v, n = strlen(s);
tot[]++;
for(int i = ; i <= n; i++)
{
bool found = false;
for(v = son[u]; v; v = bro[v])
if(ch[v] == s[i]) { found = true; break; }
if(!found)
{
v = sz++;
son[v] = ;
bro[v] = son[u];
son[u] = v;
tot[v] = ;
ch[v] = s[i];
}
ans += (tot[u] - - tot[v]) * ( * i + );
if(i == n) ans += tot[v] * ( * i + );
u = v;
tot[u]++;
}
}
}tire; const int maxl = + ;
char s[maxl]; int main()
{
//freopen("in.txt", "r", stdin); int n, kase = ;
while(scanf("%d", &n) == && n)
{
tire.clear();
ans = ;
for(int i = ; i < n; i++) { scanf("%s", s); tire.insert(s); }
printf("Case %d: %lld\n", ++kase, ans);
} return ;
}

代码君

UVa 11732 (Tire树) "strcmp()" Anyone?的更多相关文章

  1. UVa 1401 (Tire树) Remember the Word

    d(i)表示从i开始的后缀即S[i, L-1]的分解方法数,字符串为S[0, L-1] 则有d(i) = sum{ d(i+len(x)) | 单词x是S[i, L-1]的前缀 } 递推边界为d(L) ...

  2. uva 11732 (trie树)

    题意:求N个字符串两两比较,共比较了多少次? #include<iostream> #include<cstring> #include<cstdio> using ...

  3. UVA 11732 - strcmp() Anyone?(Trie)

    UVA 11732 - strcmp() Anyone? 题目链接 题意:给定一些字符串,要求两两比較,须要比較的总次数(注意.假设一个字符同样.实际上要还要和'\0'比一次,相当比2次) 思路:建T ...

  4. 左儿子右兄弟Trie UVA 11732 strcmp() Anyone?

    题目地址: option=com_onlinejudge&Itemid=8&category=117&page=show_problem&problem=2832&qu ...

  5. Codeforces 714C. Sonya and Queries Tire树

    C. Sonya and Queries time limit per test:1 second memory limit per test: 256 megabytes input:standar ...

  6. 中文分词系列(二) 基于双数组Tire树的AC自动机

    秉着能偷懒就偷懒的精神,关于AC自动机本来不想看的,但是HanLp的源码中用户自定义词典的识别是用的AC自动机实现的.唉-没办法,还是看看吧 AC自动机理论 Aho Corasick自动机,简称AC自 ...

  7. 中文分词系列(一) 双数组Tire树(DART)详解

    1 双数组Tire树简介 双数组Tire树是Tire树的升级版,Tire取自英文Retrieval中的一部分,即检索树,又称作字典树或者键树.下面简单介绍一下Tire树. 1.1 Tire树 Trie ...

  8. [数据结构]字典树(Tire树)

    概述: Trie是个简单但实用的数据结构,是一种树形结构,是一种哈希树的变种,相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串.和普通树不同的地方是,相同的字符 ...

  9. Tire树

    Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计和排序大量的字符串(但不仅限于字符串), 所以经常被搜索引擎系统用于文本词频统计. 字典树(Trie)可以保存 ...

随机推荐

  1. 开启VMware Esxi的SSH远程登录

    1.在服务器的配置页面中开启 按[F2],输入密码,进入配置页面,选择troubleshooting options,选择EnableSSH 即可. 2.在VMware Client中开启 进入:配置 ...

  2. nenu contest3 The 5th Zhejiang Provincial Collegiate Programming Contest

    ZOJ Problem Set - 2965 Accurately Say "CocaCola"!  http://acm.zju.edu.cn/onlinejudge/showP ...

  3. [转载]C# Double toString保留小数点方法

    有时候double型数据需要toString(),但又想保留小数,当值为整数,比如3.00时tostring后会变为”3″,具体说明见下: 1 string str0 = i.ToString(&qu ...

  4. PAT-乙级-1046. 划拳(15)

    1046. 划拳(15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 划拳是古老中国酒文化的一个有趣的组成部分 ...

  5. Relearning PHP (2) – php 的浮点数float

    Relearning PHP (2) – php 的浮点数float 暂无评论 php有很多坑,但是并不妨碍他是最好的语言.其他语言对于浮点数处理同样有问题,这应该是个“共有坑”.不信可以用googl ...

  6. What are Scopes?

    scope is an object that refers to the application model. It is an execution context for expressions. ...

  7. Oracle composite index column ordering

    Question:  I have a SQL with multiple columns in my where clause.  I know that Oracle can only choos ...

  8. hdu 3661 Assignments(水题的解法)

    题目 //最早看了有点云里雾里,看了解析才知道可以很简单的排序过 #include<stdio.h> #include<string.h> #include<algori ...

  9. crontab 指定执行用户

    linux下可以通过配置crontab来定时执行任务,执行体可以是一条系统命令或自己写的一个脚本,同时可以指派用户来执行.配置crontab有两种方法.方法1.使用crontab命令,例如添加一个新的 ...

  10. POJ1004Financial Management

    这个题犯了一个小小的错误,double输出的时候用f才对,输入用lf即可.... http://poj.org/problem?id=1004 #include<stdio.h> int ...