Codeforces 113B Petr# 字符串hash

题目链接:点击打开链接

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef unsigned long long ll;
const int key = 1e9 + 7;
const int N = 2000 + 2;
ll xp[N], h[N];
char a[N], b[N], c[N];
int la, lb, lc;
vector<int> posl;
vector<ll> H;

ll Hash(int s, int len) {
	return h[s] - h[s + len] * xp[len];
}

void make(char* s, ll* h, int len) {
	xp[0] = 1;
	for (int i = 1; i < N; ++i)
		xp[i] = xp[i - 1] * key;
	h[len] = 0;
	for (int i = len - 1; i >= 0; --i)
		h[i] = h[i + 1] * key + s[i];
}

int main() {
	ll hb = 0, hc = 0;
	scanf("%s%s%s", a, b, c);
	la = strlen(a);
	lb = strlen(b);
	lc = strlen(c);
	for (int i = lb - 1; i >= 0; --i)
		hb = hb * key + b[i];
	for (int i = lc - 1; i >= 0; --i)
		hc = hc * key + c[i];
	make(a, h, la);
	for (int i = 0; i + lc <= la; ++i)
		if (Hash(i, lc) == hc)
			posl.push_back(i);
	for (int i = 0; i + lb <= la; ++i)
		if (Hash(i, lb) == hb) {
			for (int j = 0; j < posl.size(); ++j) {
				if (posl[j] < i || posl[j] + lc < i + lb)
					continue;
				H.push_back(Hash(i, posl[j] + lc - i));
			}
		}
		sort(H.begin(), H.end());
		int ans = 0;
		if (H.size() > 0)
			ans = 1;
		for (int i = 1; i < H.size(); ++i)
			if (H[i] != H[i - 1])
				++ ans;
		printf("%d\n", ans);
		return 0;
}
时间: 2024-10-24 16:49:33

Codeforces 113B Petr# 字符串hash的相关文章

codeforces gym 101164 K Cutting 字符串hash

题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A: 思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N: 题目链接:传送门 #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #

Codeforces 898F 字符串hash

F. Restoring the Expression 题意:给出一个字符串,要把它折分成三部分 a.b.c , 使得 a+b=c .输出任何一种可行情况. tags:字符串 hash 因为 a+b=c ,所以 lena.lenb 至少要有一个等于 lenc 或 lenc-1  .所以枚举 lenc,每次检验一下可不可行. 但每次都暴力检验肯定超时,这里把字符串hash 一下,根据 hash值 快速检验. 记一下模板: const int mod = 1e9+7; ll Hash[N], p[N

Codeforces 39J Spelling Check hash

题目链接:点击打开链接 题意: 给定2个字符串 选择第一个字符串的其中一个字母删除,使得2个字符串完全相同 问哪些位置可以选 思路: hash求前缀后缀,然后枚举位置 #include <cstdio> #include <algorithm> #include<iostream> #include<string.h> #include <math.h> #include<queue> #include<map> #inc

hdu 1880 魔咒词典(字符串hash)

题目链接:hdu 1880 魔咒词典 题意: 给你一个10w的词典,让你输出对应的字段. 题解: map暴力存字符串肯定会卡内存,这里用BKDR字符串hash一下,用map映射一下. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef unsigned long long ull; 5 6 const int N=1e5+7,seed=133

【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】

[题目大意] 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. [字符串hash的小笔记] hash[i]=(hash[i-1]*p+idx(s[i]))%mod,idx为映射值,一般a..z映射1..26: 习惯上,p取一个6到8位的素数即可,mod一般取大素数 1e9+7(1000000007)或1e9+9(1000000009). hash[i]=(hash[i-1]*p+idx(s[i]))%mod 表示第 i 个前缀的hash值,是一个hash的前缀和,那么,要求S[l…r]

hdu4821 String 字符串hash(bkdrhash)

题意:给定m,l,一个字符串str. 我们定义一个子串为"recoverable"串 当 1.长度为 M*L 2.把这个好串分成M段,每段长度为L,且每段各不相同. 求"recoverable"串的个数,串相同位置不同也算不同. 思路:预处理数组hash,hash[i]表示从i位置到尾的字符串hash值.这里数组为unsigned long long型,因为可以自动取模.然后枚举 前l个位置,每次向后翻滚(将前一个长度为l的段hash值从map中去除,将翻滚后新出现

字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在学习后缀数组的时候已经做过一遍了,但是现在主攻字符串hash,再用字符串hash写一遍. 这题的思路是这样的: 1)取较短的串的长度作为high,然后二分答案(每次判断长度为mid=(low+high)>>1是否存在,如果存在就增加下界:不存在就缩小上界): 2)主要是对答案的判断(judge函数

uva 10391 Compound Words (字符串-hash)

Problem E: Compound Words You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is theconcatenation of exactly two other words in the dictionary. Input Standard input consists of a

[知识点] 字符串Hash

1.前言 字符串的几大主要算法都多少提及过,现在来讲讲一个称不上什么算法, 但是非常常用的东西——字符串Hash. 2.Hash的概念 Hash更详细的概念不多说了,它的作用在于能够对复杂的状态进行简单的表达,更方便的用于判重.在搜索的时候,或是动规的时候,都有过类似的做法.在实际应用中,也是非常重要的,这也就是为什么存在什么暴雪公司的Hash算法等等:加密环节也是Hash的重要之处,MD5码就是一个经典的例子. 字符串Hash的方式多式多样,重点来解释一下最简单的,最常用的. 3.BKDRHa