和普通哈希不同的是,这道题要判断匹配。
仔细想想就能发现,题目可以转化为判断每种字母有没有另一种字母与其在指定区间内的位置相同。
那我们将每种字母的出现位置哈希起来。\(sort\)判断即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2e5 + 2;
const ll mod = 1e9 + 7, base = 163;
int n, m, l, r, len, siz;
char s[N];
ll Hash[N][30], w[N], a[30], b[30];
int read() {
int x = 0, f = 1; char s;
while((s = getchar()) > '9' || s < '0') {if(s == '-') f = -1;}
while(s <= '9' && s >= '0') {
x = (x << 1) + (x << 3) + (s ^ 48);
s = getchar();
}
return x * f;
}
bool check() {
for(int i = 0; i < 26; ++ i) {
a[i] = (Hash[l + len - 1][i] - Hash[l - 1][i] * w[len] % mod + mod) % mod;
b[i] = (Hash[r + len - 1][i] - Hash[r - 1][i] * w[len] % mod + mod) % mod;
}
sort(a, a + 26); sort(b, b + 26);
for(int i = 0; i < 26; ++ i) if(a[i] ^ b[i]) return 0;
return 1;
}
void init() {
for(int i = 1; i <= n; ++ i)
for(int j = 0; j < 26; ++ j)
Hash[i][j] = (Hash[i - 1][j] * base % mod + (s[i] == j + 'a')) % mod;
w[0] = 1;
for(int i = 1; i <= n; ++ i) w[i] = w[i - 1] * base % mod;
}
int main() {
n = read(), m = read();
scanf("%s", s + 1); siz = strlen(s + 1);
init();
for(int i = 1; i <= m; ++ i) {
l = read(), r = read(), len = read();
puts(check() ? "YES" : "NO");
}
return 0;
}