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

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

ACM

题目地址:

UVA 11732 strcmp() Anyone?

题意:

问strcmp函数的==语句执行了几次。

分析:

大白上的题目。

听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下。

开始先建树记录次数,然后再遍历统计,结果错了...

后面参考了Shoutmon巨巨的写法,一边insert一边统计。

代码:

/*
*  Author:      illuz <iilluzen[at]gmail.com>
*  File:        uva11732.cpp
*  Create Date: 2014-09-24 10:30:15
*  Descripton:  trie son brother
*/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define repf(i,a,b) for(int i=(a);i<=(b);i++)
typedef long long ll;

const int N = 0;
const int MAXNODE =	4000010;

int n, cas;
ll ans;
char str[4001];

struct STrie {
	int son[MAXNODE];
	int bro[MAXNODE];
	int val[MAXNODE];
	char ch[MAXNODE];
	int sz;

	STrie() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }
	void init() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }
	// inline int idx(char c) { return c - 'a'; }

	void insert(char *s) {
		int len = strlen(s), u = 0, p;
		repf (i, 0, len) {
			// check the brother of u
			for (p = son[u]; p; p = bro[p]) {
				if (ch[p] == s[i])
					break;
			}
			// cannot find out than insert
			if (!p) {
				p = sz++;
				ch[p] = s[i];
				bro[p] = son[u];
				son[p] = 0;
				val[p] = 0;
				son[u] = p;
			}
			ans += (val[u] - val[p]) * (2 * i + 1);
			if (len == i) {
				ans += val[p] * (2 * i + 2);
				val[p]++;
			}
			val[u]++;
			u = p;
		}
	}
} trie;

int main() {
	// ios_base::sync_with_stdio(0);
	while (~scanf("%d", &n) && n) {
		trie.init();
		ans = 0;
		repf (i, 0, n - 1) {
			scanf("%s", str);
			trie.insert(str);
		}
		printf("Case %d: %lld\n", ++cas, ans);
	}
	return 0;
}
时间: 2024-10-11 21:48:34

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie)的相关文章

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

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. 分析: 大白上的题目. 听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下. 一边inser

UVA11732 &quot;strcmp()&quot; Anyone?【左儿子右兄弟Trie】

LINK1 LINK2 题目大意 给你一些字符串,并定义了一个函数(具体见题面) 问你把任意两个字符串放到函数里面得到的值的和是多少 思路 该怎么统计答案呢? 每次考虑当前插入的串和所有已经插入过的串一起统计答案 然后考虑一下怎么统计,假设当前深度是dep 并且现在是u,即将向v移动指针 那么怎么同几当前这一层的答案呢? 所有在v的子树中的节点显然是不能在这一层统计答案的 所以就考虑统计和所有不在同一个子树的答案 具体实现很简单,读者自己思考吧 注意在每一次走到字符串的末尾的时候需要特判 和他相

UVa 11732 &quot;strcmp()&quot; Anyone? (左儿子右兄弟前缀树Trie)

题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 字符串很多,又很长,如果按照题目的意思两两比较,肯定会TLE,所以要用前缀树(Trie)来解决,当然只是用简单的前缀树也会TLE的, 我们必须对其进行优化,看了

左儿子右兄弟表示法

顾名思义 每个节点一个为儿子指针,一个为兄弟指针(在加个父亲) 这样就避免了儿子个数不均带来的问题 TOJ TOJ4077 用一个指针记录当前在哪个节点,需要注意的是可以有多个重名的文件,但是不能在一个目录下. 所以用文件名和其父亲节点作为一个文件的id(区分其他). #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm

UVA - 11732 &quot;strcmp()&quot; Anyone?左兄弟右儿子trie

input n 2<=n<=4000 s1 s2 ... sn 1<=len(si)<=1000 output 输出用strcmp()两两比较si,sj(i!=j)要比较的次数,结果在long long范围内(相同字符比较两次,不相同字符比较一次,包括'\0') 做法:由于字符集太大,要用左兄弟右儿子的trie保存字符,不用每次都开ch[62]个孩子 1 #include <cstdio> 2 #include <queue> 3 #include <

UVA 11732 &quot;strcmp()&quot; Anyone? (Trie)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 题意:模拟strcmp()函数,给n个字符串,两两之间进行比较,问需要进行多少次比较? 解析:字符串很多,数据量大,按题意两两比较显然不现实.如果把所有的单词插入到一棵Trie里面会怎么样呢?考虑than和that对应的结点,than和that的前3个字符是一样的,但第4个

uva 11732 - strcmp() Anyone?(字典树)

题目链接:uva 11732 - strcmp() Anyone? 题目大意:给定n个串,然后两两之间比较,问说总共要比较多少次. 解题思路:字典树,建立出字典树,然后根据字典树的性质在节点记录有多少个字符串包含该节点.因为节点的个数比较多,所以用左孩子右兄弟的方法建立字典树. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long

UVa - 11732 - strcmp() Anyone?

先上题目: strcmp() Anyone? Time Limit:2000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description J ?strcmp()? Anyone? Input: Standard Input Output: Standard Output strcmp() is a library function in C/C++ which compares two stri

Vijos p1518 河流 转二叉树左儿子又兄弟

左儿子又兄弟的转发一定要掌握啊,竞赛必用,主要是降低编程复杂度,省时间.个人觉得状压DP也是为了降低编程复杂度. 方程就不说了,程序应该能看得懂,用的记忆化搜索,方便理解. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 bool p[103]; 6 int N,K,point[103],next[203],v[203],c[203],w[103]