这道题也是卡了挺久的。

给出一个字符串比较的算法,有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. Javascript数据类型之Undefined和null

    Javascrip中的数据类型分为原始数据类型(primitive type)和对象数据类型(object type). 原始数据类型 原始数据类型包括:数字.字符串.布尔值.null.undefin ...

  2. 常用的Eclilpse插件列表以及安装方式总结

    Eclipse常用插件的安装方式总结: 1.Maven Integration for Eclipse WTP     作用:用来方便开发和使用maven项目.     安装方式:Eclipse Ma ...

  3. 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 n<=39

    // test14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  4. grunt安装失败处理

    1.官网 Grunt官网 http://gruntjs.com 2.前言 前段时间一不小心升级了win10(万恶的360),各种不适应各种问题各种软件bug,最终决定回退到win7,然后悲催的发现系统 ...

  5. [SQL Server系] -- 约束

    什么是约束? 约束(Constraint)是SQL Server中提供的 自动保存数据库完整性 的一种方法,定义了可输入表或表的列中的数据限制条件. SQL Server中共有5中约束 PRIMARY ...

  6. 安装ubuntu vi编辑无法正常使用的时候 如方向键变成ABCD

    http://blog.sina.com.cn/s/blog_7e3f6e8f0100vkon.html 在使用ubuntu的时候,发现vi编辑模式下退格键backspace和上下左右光标移动键不能用 ...

  7. MongoDB安装(Linux)

    下载文件 http://downloads.mongodb.org/linux/mongodb-linux-i686-static-2.5.0.tgz 解压: tar -zxvf mongodb-li ...

  8. Project Euler 81:Path sum: two ways 路径和:两个方向

    Path sum: two ways In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom ...

  9. python自省指南

    深入python中对自省的定义: python的众多强大功能之一,自省,正如你所知道的,python中万物皆对象,自省是指代码可以查看内存中以对象形式存在的其他模块和函数,获取它们的信息,并对它们进行 ...

  10. ios UIView常用动画效果

    一 //调用 1 2 3 4 5 6 if(m_viewScenario.superview == nil)<br>{     m_viewScenario.alpha = 1.0;    ...