字符串哈希
首先对于知识点会在8月份更新,目前只是单纯题目进行展示
1001.循环位移
题意:
定义一个字符串[A] 它代表着是一个循环位移的字符串. 给你T组数据,字符串A, B.问你在B字符串中有多少子串是[A]
分析样例:

如何解决这个问题,我的方法是字符串哈希
为了处理 A 的循环位移,代码将 A 自身与自身拼接,形成 A+A。这样,所有可能的循环位移都可以作为 A+A 的子串出现 就将所有A的循环位移字符串的哈希值储存进map里 再去枚举B的长度为A的哈希值,去B的长度为A统计是否映射进A里,累加答案就是最终答案
Code:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N = 1048580 * 2;
const int P = 131;
ull p[N], h1[N], h2[N];
void solve() {
string a, b;
cin >> a >> b;
int n = a.size(), m = b.size();
a = a + a;
for (int i = 0; i < (n << 1); i++) {
h1[i + 1] = h1[i] * P + a[i];
}
for (int i = 0; i < m; i++) {
h2[i + 1] = h2[i] * P + b[i];
}
map <ull, int> mp;
for (int i = 0; i < n; i++) {
mp[h1[i + n] - h1[i] * p[n]]++;
}
int ans = 0;
for (int i = 0; i <= m - n; i++) {
ans += mp[h2[i + n] - h2[i] * p[n]];
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
p[0] = 1;
for (int i = 1; i < N; i++) {
p[i] = p[i - 1] * P;
}
int _; cin >> _;
while(_--) solve();
return 0;
}
例题链接 (考验哈希,其他解法会通过后续更新)
https://ac.nowcoder.com/acm/contest/87255/E
题意:
题目要求我们找出两个等长的字符串 a 和 b 中的“好”字符数量。一个字符被称为“好”字符, 如果它在字符串 a 和 b 的所有循环同构字符串中出现的位置是一致的。换句话说,对于每个 字符 x,要么在字符串 a 和 b 的每个位置都出现,要么都不出现。
思路: (根据现有条件 加上 我的哈希大法 快速解决这题)
和上面一样 也有个循环位移,但是这里多了个判断好字符, 在进行字符 x 进行判断时,可以发挥自己聪明的大脑 想到 如果这个出现要么这一位是一样的 要么是不一样的 那是不是可以转换为是不是字符x转换为01串(这里简约一下)。字符串哈希 恰恰好可以求出我当前的值是不是满足这个情况 那么这题就会迎刃而解了 请看Code
Code:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N = 1e6 + 10;
const int P = 131;
ull h1[N << 1], h2[N], p[N << 1] = {1};
void geth(ull h[], const string &s, char c) {
int len = s.size();
for (int i = 1; i < len; i++) {
h[i] = h[i - 1] * P + (s[i] == c);
}
}
ull get(const ull h[], int l, int r) {
return h[r] - h[l - 1] * p[r - l + 1];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(15);
int n;
cin >> n;
string a, b;
cin >> a >> b;
set<char> st(a.begin(), a.end());
a = '%' + a + a;
b = '%' + b;
for (int i = 1; i <= n * 2; i++) {
p[i] = p[i - 1] * P;
}
int ans = 0;
for (char c : st) {
geth(h1, a, c);
geth(h2, b, c);
for (int i = 1; i <= n; i++) {
if (get(h1, i, i + n - 1) == get(h2, 1, n)) {
ans++;
break;
}
}
}
cout << ans;
return 0;
}
2

浙公网安备 33010602011771号