【模板】字符串哈希

前言

均使用unsigned long long溢出自动取模;

非unsigned long long版本:OI-wiki 字符串hash

详解

模板

预处理进制B的次方

void init_bp(){
	bp[0][0] = bp[1][0] = 1;
	for(int i=1;i<=hs;i++){ // hs: 字符串最大长度
		bp[0][i] = bp[0][i-1]*B1;
		bp[1][i] = bp[1][i-1]*B2;
	} 
}

前缀hash

void add_ha(int x){ // 1...len
	++tha;
	ha[0][tha] = ha[0][tha-1]*B1 + x;
	ha[1][tha] = ha[1][tha-1]*B2 + x;
}

l...r的hash值

LL get_ha(int wh,int l,int r){ // 1...len
	return ha[wh][r] - ha[wh][l-1]*bp[wh][r-l+1];
}

例题

例题一

ACwing 兔子与兔子

#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
#define LL long long
#define ll long long
#define ULL unsigned long long
#define ls rt<<1
#define rs rt<<1|1
#define MS 1000009
#define INF 1e18
#define mod 998244353
#define Pi acos(-1.0)
#define Pair pair<LL,LL>
#define B1 131
#define B2 13331

LL n,m,k;
char s[MS];
LL hs;
ULL bp[2][MS];
ULL ha[2][MS],tha;

void init_bp(){
	bp[0][0] = bp[1][0] = 1;
	for(int i=1;i<=hs;i++){
		bp[0][i] = bp[0][i-1]*B1;
		bp[1][i] = bp[1][i-1]*B2;
	} 
}

void add_ha(int x){
	++tha;
	ha[0][tha] = ha[0][tha-1]*B1 + x;
	ha[1][tha] = ha[1][tha-1]*B2 + x;
}

LL get_ha(int wh,int l,int r){
	return ha[wh][r] - ha[wh][l-1]*bp[wh][r-l+1];
}

int main() {
	ios::sync_with_stdio(false);
	cin >> s+1;
	hs = strlen(s+1);
	init_bp();
	for(int i=1;i<=hs;i++){
		add_ha(s[i]-'a'+1);
	}
	cin >> m;
	while(m--){
		LL l1,r1,l2,r2;
		cin >> l1 >> r1 >> l2 >> r2;
		if(get_ha(0,l1,r1) == get_ha(0,l2,r2) && get_ha(1,l1,r1) == get_ha(1,l2,r2)) cout << "Yes\n";
		else cout << "No\n";
	}
	
	
	return 0;
}

例题二

洛谷P3370 【模板】字符串哈希

#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <map>
using namespace std;
#define LL long long
#define ll long long
#define ULL unsigned long long
#define ls rt<<1
#define rs rt<<1|1
#define MS 100009
#define INF 1e18
#define mod 998244353
#define Pi acos(-1.0)
#define Pair pair<LL,LL>
#define B1 131
#define B2 13331

LL n,m,k;
char s[MS];
LL hs;
ULL bp[2][MS];
ULL ha[2][MS],tha;
map<ULL,map<ULL,ULL> > mp;

void init_bp(){
	bp[0][0] = bp[1][0] = 1ll;
	for(int i=1;i<=2000;i++){
		bp[0][i] = bp[0][i-1]*B1;
		bp[1][i] = bp[1][i-1]*B2;
	}
}

void add_ha(LL x){
	++tha;
	ha[0][tha] = ha[0][tha-1]*B1+x;
	ha[1][tha] = ha[1][tha-1]*B2+x;
}

ULL get_ha(int wh,int l,int r){
	return ha[wh][r] - ha[wh][l-1]*bp[wh][r-l+1];
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n;
	LL ans = 0;
	while(n--){
		cin >> s+1;
		LL hs = strlen(s+1);
		tha = 0;
		for(int i=1;i<=hs;i++){
			add_ha(s[i]);
		}
		ULL t1 = get_ha(0,1,hs);
		ULL t2 = get_ha(1,1,hs);
		if(!mp[t1][t2]){
			mp[t1][t2] = 1ull;
			ans++;
		}
	}
	cout << ans << endl;
	
	return 0;
}
posted @ 2021-03-16 15:46  棉被sunlie  阅读(105)  评论(0)    收藏  举报