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)可以保存 ...
随机推荐
- SQL Server 2008之数据库大型应用解决方案总结
着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的互联网应用,每天百万级甚至上亿的PV无疑对数据库造成了相当高的负载.对于系统的稳定性和扩展性造成了极大的问题. 一. ...
- [algothrim]URL相似度计算的思考
http://www.spongeliu.com/399.html http://in.sdo.com/?p=865
- 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- windows 64位整数
#include <iostream> #include <ctime> using namespace std; int main() { cout << cou ...
- 使用EF code first和asp.net mvc4遇到的问题总结
最近使用EF code first和asp.net mvc4做项目,遇到些问题,记录一下. 一.EF code first 生成外键列问题. 一般情况下,都是先写一个int型外键id属性,然后写一个外 ...
- yum源万能
sed -i ‘s|^#baseurl|baseurl| ; s|^mirrorlist|#mirrorlist|’ /etc/yum.repos.d/*
- C++ Variables and Basic Types Notes
1. Type conversion: If we assign an out-of-range value to an object of unsigned type, the result is ...
- utmp, wtmp, and lastlog 日志清除工具
utmp, wtmp, and lastlog 日志清除工具 http://blog.itpub.net/83980/viewspace-801664/
- HBase入门
/×××××××××××××××××××××××××××××××××××××××××/ Author:xxx0624 HomePage:http://www.cnblogs.com/xxx0624/ ...
- Happy Number
https://leetcode.com/problems/happy-number/ Write an algorithm to determine if a number is "hap ...