CF985F 补题
F Isomorphic Strings(Educational Codeforces Round 44 F)
难度:2300
赛时想到哈希,但是不知道怎么哈
一个长度为n的字符串,它所有字符的情况可以由26个长度为n的01串表示
而这个长度为n的01串可以被哈希化为一个整数,因此只需要26个整数就可以表示一个字符串的所有字母的分布情况
判断两个字符串是否是同构的,只需要判断它们的26个整数是否相等即可
因此对于这道题,我们用f[i][c]表示前i个字符中,字符c的分布情况对应的哈希值,就能在\(O(26)\)知道任何一个区间的字符分布情况:
也就是把26个哈希值塞进一个vector并排序,得到的vector就代表了这个区间的字符分布情况
#include<bits/stdc++.h>
using namespace std;
#define LL unsigned long long
const LL mod = 1e9+7;
const LL base=131;
const int maxn = 200005;
LL f[maxn][26],bs[maxn];
LL query(int l,int r,int c)
{
if(l==0)return f[r][c];
return (f[r][c]-f[l-1][c]*bs[r-l+1]%mod+mod)%mod;
}
void solve()
{
int n,m;
cin>>n>>m;
string s;
cin>>s;
for(int i=0;i<s.length();i++)
{
for(int j=0;j<26;j++)
{
if(i==0)f[i][j]=s[i]==(j+'a');
else f[i][j]=(f[i-1][j]*base%mod+(s[i]==(j+'a'))) % mod;
}
}
bs[0]=1;
for(int i=1;i<n;i++)
{
bs[i]=bs[i-1]*base%mod;
}
while(m--)
{
int x,y,len;
vector<int>a,b;
cin>>x>>y>> len;
x--; y--;
for(int i=0;i<26;i++)
{
a.push_back(query(x,x+len-1,i));
b.push_back(query(y,y+len-1,i));
}
sort(a.begin(),a.end());
sort(b.begin(),b.end());
if(a == b)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
}
int main()
{
int T=1;
while(T --> 0)
{
solve();
}
return 0;
}