985F Isomorphic Strings(字串Hash雜湊)
F. Isomorphic Strings
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a string s of length n consisting of lowercase English letters.
For two given strings s and t, say S is the set of distinct characters of s and T
- f(si) = ti for any index i,
- for any character there is exactly one character that f(x) = y,
- for any character
For example, the strings "aababc" and "bbcbcz" are isomorphic. Also the strings "aaaww" and "wwwaa" are isomorphic. The following pairs of strings are not isomorphic: "aab" and "bbb", "test" and "best".
You have to handle m queries characterized by three integers x
Input
The first line contains two space-separated integers n and m (1 ≤ n ≤ 2·105, 1 ≤ m ≤ 2·105) — the length of the string s and the number of queries.
The second line contains string s consisting of n lowercase English letters.
The following m lines contain a single query on each line: xi, yi and leni (1 ≤ xi, yi ≤ n, 1 ≤ leni ≤ n - max(xi, yi) + 1) — the description of the pair of the substrings to check.
Output
For each query in a separate line print "YES" if substrings s[xi... xi + leni - 1] and s[yi... yi + leni - 1] are isomorphic and "NO" otherwise.
Example
input
Copy
7 4 abacaba 1 1 1 1 4 2 2 1 3 2 4 3
output
Copy
YES YES NO YES
Note
The queries in the example are following:
- substrings "a" and "a" are isomorphic: f(a) = a;
- substrings "ab" and "ca" are isomorphic: f(a) = c, f(b) = a;
- substrings "bac" and "aba" are not isomorphic since f(b) and f(c) must be equal to a at same time;
- substrings "bac" and "cab" are isomorphic: f(b) = c, f(a) = a, f(c) = b.
題意:給你一個字串,問你裡面兩個長度相同的子串,裡面的字母能否一一對應
解題思路:把一個字串拆成26個01字串,如abcdbc變為
100000
010010
001001
000100
...
然後對這些字串做雜湊,每次查詢每個字母的子串的hash值是否相等即可。
這裡用來儲存字串雜湊模板
#include <iostream>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int MAXN = 200005;
struct HashTable
{
ull g[MAXN];
ull P1 = 1997;
ull P2 = 10000007;
ull Hash[MAXN];
ull getHash(int x, int len)
{
return ((Hash[x + len - 1] - Hash[x - 1] * g[len] % P2) + P2) % P2;
}
void hash(char *s, int len)
{
g[0] = 1;
for (int i = 1; i <= MAXN-1; i++)
g[i] = (g[i - 1]) * P1 % P2;
for (int i = 1; i <= len; i++)
Hash[i] = (Hash[i - 1] * P1 + s[i - 1]) % P2;
}
};
HashTable table[26];
char s[MAXN];
char a[26][MAXN];
int ans1[MAXN];
int ans2[MAXN];
int main()
{
int N, Q;
scanf("%d%d", &N, &Q);
scanf("%s", s);
int len = strlen(s);
for (int i = 0; i < len; i++)
{
for (int j = 0; j < 26; j++)
{
a[j][i] = ((s[i] - 'a') == j) + 1;
}
}
for (int i = 0; i < 26; i++)
{
table[i].hash(a[i], len);
}
int x, y, l;
while (Q--)
{
scanf("%d%d%d", &x, &y, &l);
for (int i = 0; i < 26; i++)
{
ans1[i] = table[i].getHash(x, l);
ans2[i] = table[i].getHash(y, l);
}
sort(ans1, ans1 + 26);
sort(ans2, ans2 + 26);
bool flag = 0;
for (int i = 0; i < 26; i++)
{
if (ans1[i] != ans2[i])
{
flag = 1;
cout << "NO" << endl;
break;
}
}
if (flag == 0)
cout << "YES" << endl;
}
return 0;
}