哈希相关

双哈希

#include<bits/stdc++.h>
using namespace std;
const int B1=131; 
const int B2=137;
typedef unsigned long long ull;
int n;
string a;
map<pair<ull,ull>,ull>mp;
void use_hash(){
	ull h1=0;
	for(int i=0;i<a.size();i++)h1=h1*B1+a[i];
	ull h2=0;
	for(int i=0;i<a.size();i++)h2=h2*B2+a[i];
	mp[{h1,h2}]++;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a,use_hash();
	cout<<mp.size();
	return 0;
}

初学者比较容易犯一个思路上的错误:使用两个map分别存储再分别判断。但实际上,双哈希的思路是使用两种进制(其实有可能还会配套使用两个模数,但是如果你用unsigned long long自然溢出,就不需要管模数)算出两个结果,然后将两个结果绑在一起去判断。

哈希相关题目

饭堂

题目大意:一个字符串被称为\(k-\)回文串当且仅当它本身是回文串,且它长度为\(\lfloor\frac{n}{2}\rfloor\)的前缀和后缀是\((k-1)-\)回文串。任意字符串(包括空串)都是\(0-\)字符串。一个字符串的回文度数就是这个字符串的\(k\)的最大值。而对于一个给定的字符串,它的和谐程度就是其所有前缀回文度数之和。求一个字符串的和谐程度。字符串长度\(\le5e6+5\)

解决思路:这题的正解其实并不是哈希。不过确实可以使用哈希解决。遍历整个字符串前缀,判断它是否是回文串,再分别判断它的前后半段是否是回文串。如果是就进行\(k\)的累加

实现细节:实现方面又两个难点,一个是哈希判断回文串,另一个则是\(k\)的累加。这两个板块都挺难写的,我一个一个来讲。

哈希判断回文串

首先,需要把原来的字符串进行翻转

for(int i=a.size()-1;i>=0;i--)rev_a=rev_a+a[i];

分别处理翻转之前和翻转之后的字符串哈希值

for(int i=1;i<a.size();i++)a_pre[i]=a_pre[i-1]*B+a[i];
for(int i=1;i<rev_a.size();i++)rev_pre[i]=rev_pre[i-1]*B+rev_a[i];
posted @ 2026-07-21 10:17  Baltic  阅读(2)  评论(0)    收藏  举报