UVa 11732 (Tire树) "strcmp()" Anyone?
这道题也是卡了挺久的。
给出一个字符串比较的算法,有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?的更多相关文章
- 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) ...
- uva 11732 (trie树)
题意:求N个字符串两两比较,共比较了多少次? #include<iostream> #include<cstring> #include<cstdio> using ...
- UVA 11732 - strcmp() Anyone?(Trie)
UVA 11732 - strcmp() Anyone? 题目链接 题意:给定一些字符串,要求两两比較,须要比較的总次数(注意.假设一个字符同样.实际上要还要和'\0'比一次,相当比2次) 思路:建T ...
- 左儿子右兄弟Trie UVA 11732 strcmp() Anyone?
题目地址: option=com_onlinejudge&Itemid=8&category=117&page=show_problem&problem=2832&qu ...
- Codeforces 714C. Sonya and Queries Tire树
C. Sonya and Queries time limit per test:1 second memory limit per test: 256 megabytes input:standar ...
- 中文分词系列(二) 基于双数组Tire树的AC自动机
秉着能偷懒就偷懒的精神,关于AC自动机本来不想看的,但是HanLp的源码中用户自定义词典的识别是用的AC自动机实现的.唉-没办法,还是看看吧 AC自动机理论 Aho Corasick自动机,简称AC自 ...
- 中文分词系列(一) 双数组Tire树(DART)详解
1 双数组Tire树简介 双数组Tire树是Tire树的升级版,Tire取自英文Retrieval中的一部分,即检索树,又称作字典树或者键树.下面简单介绍一下Tire树. 1.1 Tire树 Trie ...
- [数据结构]字典树(Tire树)
概述: Trie是个简单但实用的数据结构,是一种树形结构,是一种哈希树的变种,相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串.和普通树不同的地方是,相同的字符 ...
- Tire树
Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计和排序大量的字符串(但不仅限于字符串), 所以经常被搜索引擎系统用于文本词频统计. 字典树(Trie)可以保存 ...
随机推荐
- Windows 7 下配置IIS,并且局域网内可访问
win7的iis很麻烦滴!我搭建过一次!不过有点问题!还是xp好! 一.进入Win7的 控制面板,选择左侧的 打开或关闭Windows功能 . 二.现在出现了安装Windows功能的选项菜单,注意选择 ...
- 只是一个用EF写的一个简单的分页方法而已
只是一个用EF写的一个简单的分页方法而已 慢慢的写吧.比如,第一步,先把所有数据查询出来吧. //第一步. public IQueryable<UserInfo> LoadPagesFor ...
- How to use Android Activity's finish(), onDestory() and System.exit(0) methods
Activity.finish() Calling this method will let the system know that the programmer wants the current ...
- 1833: [ZJOI2010]count 数字计数 - BZOJ
Description给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次.Input输入文件中仅包含一行两个整数a.b,含义如上所述.Output输出文件中包含一 ...
- 剑指offer--面试题14--收获
按照作者的说法,作为应届毕业生的我来说,如果能写出初级程序员的参考代码来解决面试题14就可认为过关了... 参考代码如下: void ReorderOddEven_1(int *pData, unsi ...
- [转载]DirectoryEntry配置IIS7出现ADSI Error:未知错误(0x80005000)
一.错误情况 环境:win7+iis7.0 DirectoryEntry配置IIS7出现如下错误 或者是 下面一段代码在IIS6.0下运转正常,但IIS7.0下运转会出错: System.Direct ...
- MATLAB三维散点图的绘制(scatter3、plot3)
MATLAB三维散点图的绘制(scatter3.plot3) (1)函数scatter3 用法:scatter3(x,y,z,'.',c) % c 为颜色,需和x,y,z长度相同 例子: x=[422 ...
- 用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理
用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理 我测了一组数据存到txt文件中,是个WIFI信号强度文档,里面有我们需要得到的数据,有没用的数据,想用matla ...
- PHP之preg_replace()与ereg_replace()正则匹配比较讲解
<?php //preg_replace()和ereg_replace()函数的使用的比较 // -------preg_replace()-------------------------- ...
- 在 tornado 中异步无阻塞的执行耗时任务
在 tornado 中异步无阻塞的执行耗时任务 在 linux 上 tornado 是基于 epoll 的事件驱动框架,在网络事件上是无阻塞的.但是因为 tornado 自身是单线程的,所以如果我们在 ...