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;
}
posted @ 2025-07-14 21:33  arthalter  阅读(8)  评论(0)    收藏  举报