UVA - 12338 Anti-Rhyme Pairs (哈希)

Description


D


Anti-Rhyme Pairs

Input: Standard Input

Output: Standard Output


Often two words that rhyme also end in the same sequence of characters. We use this property to define the concept of an anti-rhyme. An anti-rhyme is a pair of words that have a similar beginning. The degree of anti-rhyme of a pair of words is further defined
to be the length of the longest string S such that both strings start withS. Thus, “arboreal” and “arcturus” are an anti-rhyme pair of degree 2, while “chalkboard” and “overboard” are an anti-rhyme pair of degree 0.

You are given a list of words. Your task is, given a list of queries in the form(i, j), print the degree of anti-rhyme for the pair of strings formed by thei-th and the
j-th words from the list.

Input

Input consists of a number of test cases. The first line of input contains the number of test casesT (T ≤ 35). Immediately following this line are
T cases.

Each case starts with the number of strings N (1 ≤ N ≤ 105) on a line by itself. The followingN lines each contain a single non-empty string made up entirely of lower case English characters (‘a‘ to ‘z‘), whose
lengthL is guaranteed to be less than or equal to 10,000. In every case it is guaranteed thatN*L ≤ 106.

The line following the last string contains a single integer Q (1 ≤ Q ≤ 106), the number of queries. Each of theQ lines following contain a query made up of two integers
i and j separated by whitespace (1 ≤ i, j ≤ N).

Output

The output consists of T cases, each starting with a single line with“Case X:”, where
X indicates the X-th case. There should be exactlyQ lines after that for each case. Each of those
Q lines should contain an integer that is the answer to the corresponding query in the input.

Sample Input                            Output for Sample Input


2

5

daffodilpacm

daffodiliupc

distancevector

distancefinder

distinctsubsequence

4

1 2

1 5

3 4

4 5

2

acm

icpc

2

1 2

2 2


Case 1:

8

1

8

4

Case 2:

0

4

题意:给你n个字符串,让你求给定的两个串的最长公共前缀

思路:预处理是无法达到时间要求的,那么我们能够先hash处理出每一个字符串每一个字符的哈希值(这个值是递增),然后就能二分的比較查询了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1000005;
const int seed = 31;

char str[maxn];
int start[maxn], len[maxn];
ll hash[maxn];

int cal(int a, int b) {
	int l = 0, r = min(len[a], len[b]);
	while (l < r) {
		int m = (l + r + 1) >> 1;
		if (hash[start[a]+m-1] == hash[start[b]+m-1])
			l = m;
		else r = m-1;
	}
	return l;
}

int main() {
	int t, n, cas = 1;
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		int cur = 0;
		for (int i = 0; i < n; i++) {
			scanf("%s", str+cur);
			len[i] = strlen(str+cur);
			start[i] = cur;
			hash[cur] = str[cur] - 'a';
			for (int j = 1; j < len[i]; j++)
				hash[cur+j] = hash[cur+j-1] * seed + str[cur+j] - 'a';
			cur += len[i];
		}
		scanf("%d", &n);
		printf("Case %d:\n", cas++);
		int a, b;
		while (n--) {
			scanf("%d%d", &a, &b);
			printf("%d\n", cal(a-1, b-1));
		}
	}
	return 0;
}
时间: 2024-12-17 16:32:48

UVA - 12338 Anti-Rhyme Pairs (哈希)的相关文章

UVA 12338:Anti-Rhyme Pairs(后缀数组+ST表)

[题目链接] click [题目大意] 给出一些字符串,询问查询任意两个字符串的最长公共前缀 [题解] 将字符串拼接,对拼接的字符串做后缀数组,对于查询的两个字符串, 只要在height数组上查询区间最小值即可. 特别注意多组数据时候对字符串结尾的处理,很久没写容易忽视导致wa. [代码] #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=

uva 12338 - Anti-Rhyme Pairs(后缀数组+RMQ)

题目链接:uva 12338 - Anti-Rhyme Pairs 题目大意:给定若干个字符串,每次询问两个字符串的最长公共前缀. 解题思路:本来应该将每个字符串连接起来做后缀数组,但其实可以直接把一个字符串看成是一个字符,然后排序了就对应是SA数组,然后处理height即可.然后根据后缀数组的性质,字符串i和j的最长公共前缀长度即为rank[i]+1~rank[j]之间height的最小值.特判i=j的情况. #include <cstdio> #include <cstring>

UVA 12338 哈希+二分最长前缀

每个字符串都哈希之后,二个之间二分出最长前缀! 需要注意的是不能用数组存,会暴,用vector就行了. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue&g

UVA - 12338 Anti-Rhyme Pairs 二分+hash

题目链接:https://vjudge.net/problem/UVA-12338 题意: 给你n个串 问你任意两个串的最大公共前缀长度是多少 题解: 二分+hash 思路很明显,我最近用来写hash 很鸡肋 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls

《转》python学习(9)字典

转自 http://www.cnblogs.com/BeginMan/p/3156960.html 一.映射类型 我理解中的映射类型是:键值对的关系,键(key)映射值(value),且它们是一对多的关系.字典是Python唯一的映射类型. 扩展1:哈希表一种数据结构,值是根据相关的键进行数据存储的,形成"键-值对"(key-value pairs),哈希表中的值是没有顺序的. 扩展2:映射类型与序列类型的区别 1):访问方式不同,序列类型用数字类型的键,而映射类型可以用其他对象类型做

uva 12206 - Stammering Aliens(哈希)

题目链接:uva 12206 - Stammering Aliens 题目大意:给出一个字符串,找出至少出现m次的最长子串. 解题思路:哈希算法,将每个后缀数组建立一个哈希值,每次二分长度判断,每次判断时将哈希值排序,计数即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ll; const int ma

uva 1390 - Interconnect(期望+哈希+记忆化)

题目连接:uva 1390 - Interconnect 题目大意:给出n表示有n个点,m表示有m条边,现在任选两点建立一条边,直到整个图联通,问说还需建立边数的期望,建过边的两点仍可以建边. 解题思路:哈希的方法很是巧妙,将各个联通分量中节点的个数c[i]转换成一个30进制的数(因为节点个数最多为30),因为结果很大,所以对1e5+7取模.获得的哈希值作为插入和搜索的起点. #include <cstdio> #include <cstring> #include <alg

uva 12326 &amp; hdu 4092 - Yummy Triangular Pizza(哈希+打表)

题目链接:uva 12326 &hdu 4092 Yummy Triangular Pizza 题目大意:给出n,表示用n个正三角形去组成图形,问可以组成多少种不同的三角形,旋转,镜像,都算同一种. 解题思路:参考别人的思路,很巧妙,主要就是建立三维坐标轴. 正立三角形x+y+z = 0 倒立三角形x+y+z ≠ 0 这样从初始装态为0 0 0的三角形开始逐个添加,每次进行旋转镜像,判断是否有没有重复. 每次判断重复的时候,枚举图形中的一个三角做为原点处理,生成hash值,以为n为多位16,所以

UVA 11019 字符矩阵哈希

思路:以前没做过字符矩阵的哈希,所以这题是看别人博客写的. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<set>