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)可以保存 ...
随机推荐
- sqlserver 获取时间年月日时分秒
转自:http://blog.itpub.net/14766526/viewspace-1156100/ select GETDATE() as '当前日期',DateName(year,GetDat ...
- JSP访问Spring中的bean
JSP访问Spring中的bean <%@page import="com.sai.comment.po.TSdComment"%> <%@page import ...
- JS中的className含义
问题描述: JS中的className含义 问题解决: className说明: className属性可以设置和返回元素的class属性 可以有两种方法来获取对象的c ...
- WCF 基础
ServiceModel 配置元素 Binding 配置元素: 客户端Web.config: <?xml version="1.0" encoding="utf-8 ...
- ios开发之多线程资源争夺
上一篇介绍了常用的多线程技术,目前开发中比较常用的是GCD,其它的熟悉即可.多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用率来提高系统的整体性能,但是会出现多个线程对同一资源 ...
- hdu 2196
树形dp 本文出自 http://blog.csdn.net/shuangde800 题目传送门 题意: 给出一棵树,求离每个节点最远的点的距离 思路: 把无根树转化成有根树分析, 对于上面那棵树 ...
- iOS 委托和协议区别和联系
iOS上的协议类似于C#.Java上面的接口,他是从类中抽出来的一系列方法,但方法的实现是在实现这个协议的类中,任何实现这个协议的类都需要实现协议类中的@require方法: 委托是一种设计模式,是一 ...
- unit3d 4.6 document open solution
发现4.6 的 本地 文档字体解析采用 fonts.googleapis.com ,可是google 自古就与天朝不在一个鼻孔,所以你打开往往需要半天. 网上查了一下,把所有本地的*.html 文档 ...
- IOS版UC我的视频地址
UC浏览器/Library/Application Support/offlineVideos
- StringBuffer用法
public class StringBufferTest { public static void main(String[] args) { StringBuffer sb=new StringB ...