Description:
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 is the set of distinct characters of t. The strings s and t are isomorphic if their lengths are equal and there is a one-to-one mapping (bijection) f between S and T for which f(si) = ti. Formally:
f(si) = ti for any index i,
for any character there is exactly one character that f(x) = y,
for any character there is exactly one character that f(x) = y.
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, y, len (1 ≤ x, y ≤ n - len + 1). For each query check if two substrings s[x… x + len - 1] and s[y… y + len - 1] are isomorphic.
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.
题意:
给定一个长度为n的字符串,和m次起点分别为l和r的长度为len的合法与否询问,结果输出YES或NO(即从s[l]到s[l+len-1]的子串和从s[r]到s[r+len-1]的子串是否合法映射)
我们可以将利用哈希函数将原串构造成01串,进制为base(自己定),定义一个hashh二维数组,
hashh[i][j](比如hash[i][1]表示第i个位置是字母a的哈希值,如果是a,该位置为1,不是为0)
比如aabbc和cceef两个子串,因为如果映射合法,必然a对应c,b对应e,c对应f
所以对两个子串分别从a~z的26种情况计算哈希值并存入a[26]和b[26],排序后,如果映射合法,两个数组一定每个位置一一对应相等,有一处不同则不合法
ac代码如下
#include
#include
using namespace std;
typedef long long ll;
const ll base = 131, maxn = 2e5 + 5, mod = 1e9 + 5;
ll n, m;
char s[maxn];
ll sum[maxn];
ll hashh[maxn][30];//比如hashh[i][1]表示第i个字符为a的哈希值
ll l, r, len;
void init()//初始化hashh和sum数组
{
for (ll i = 1; i <= n; i++)
{
for (ll j = 1; j <= 26; j++)
{
hashh[i][j] = (hashh[i-1][j] * base % mod + ll(s[i] == 'a' + j - 1)) % mod;
}
}
sum[0] = 1;
for (ll i = 1; i <= n; i++)
{
sum[i] = sum[i - 1] * base % mod;
}
}
bool judge()
{
ll a[27], b[27];
for (int i = 1; i <= 26; i++)
{
a[i] = (hashh[l + len - 1][i] - hashh[l - 1][i] * sum[len] % mod + mod) % mod;
b[i] = (hashh[r + len - 1][i] - hashh[r - 1][i] * sum[len] % mod + mod) % mod;
}
sort(a + 1, a + 27);
sort(b + 1, b + 27);
for (int i = 1; i <= 26; i++)
{
if (a[i] != b[i])
return 0;
}
return 1;
}
int main()
{
cin >> n >> m;
scanf("%s", s + 1);
init();
while(m--)
{
cin >> l >> r >> len;
if (judge())
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}