CF985F Isomorphic Strings (哈希)
哈希
对于两个串是否匹配,我们显然不关心字母是什么,而关心每个字母占有的位置是什么,如果每个字母占有的位置构成的集合相同,那么就是匹配的。于是就类似字符串哈希一样哈希字母位置。将集合排序后比较,就做完了。
复杂度 \(O(26m)\)。
#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define fi first
#define se second
#define pb push_back
using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 10, p = 20242024, mod = 1234567891;
int n, m;
std::string s;
i64 hsh[28][N];
i64 ret1[30], ret2[30];
i64 qpow(i64 a, i64 b) {
i64 ret = 1;
while(b) {
if(b & 1) ret = ret * a % mod;
a = a * a % mod;
b >>= 1;
}
return ret;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> m >> s;
s = '#' + s;
for(int c = 0; c < 26; c++) {
for(int i = 1; i <= n; i++) {
if(s[i] - 'a' == c) {
hsh[c][i] = (hsh[c][i - 1] * p % mod + 1) % mod;
} else hsh[c][i] = hsh[c][i - 1] * p % mod;
}
}
while(m--) {
int x, y, l;
std::cin >> x >> y >> l;
bool flg = 1;
i64 pw = qpow(p, l);
for(int i = 0; i < 26; i++) {
ret1[i] = (hsh[i][x + l - 1] - hsh[i][x - 1] * pw % mod + mod) % mod;
ret2[i] = (hsh[i][y + l - 1] - hsh[i][y - 1] * pw % mod + mod) % mod;
}
std::sort(ret1, ret1 + 26);
std::sort(ret2, ret2 + 26);
for(int i = 0; i < 26; i++) {
if(ret1[i] != ret2[i]) flg = 0;
}
std::cout << (flg ? "YES\n" : "NO\n");
}
return 0;
}