Codeforces 985F-Isomorphic Strings
题意
给定一个字符串\(s\),长为\(n\)。\(m\)组询问,每次询问给出\(x\),\(y\),\(len\),问是否存在一一映射,使得\(s\)中起点为\(x\)长度为\(len\)的子串能映射成起点为\(y\),长度为\(len\)的子串。
题解
是否存在映射取决于字母的排列情况是否一致。我们可以以26个字母分别为关键字将整个字符串\(s\)表示成一个0,1串(如字符串“aabcc”,以a为关键字“11000”,b为关键字“00100”,c为关键字“00011”,其余字母为关键字均为“00000”),那么,如果两个字串相等,他们26个0,1串排好序后就应该一致。我们可以用hash来比较0,1串是否一致。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
const int base=131;
const ll mod=1e9+7;
char s[N];
ll h[30][N];
ll sum[N];
ll a[30],b[30];
int len,n,t;
void Hash(){
for(int i=0;i<26;i++){
for(int j=1;j<=len;j++){
ll x;
if(s[j]=='a'+i) x=1;
else x=0;
h[i][j]=(h[i][j-1]*base%mod+x)%mod;
}
}
}
void init(){
sum[0]=1;
for(int i=1;i<=len;i++){
sum[i]=(sum[i-1]*base)%mod;
}
}
bool solve(int l,int r,int d){
for(int i=0;i<26;i++){
a[i]=(h[i][l+d-1]-h[i][l-1]*sum[d]%mod+mod)%mod;
b[i]=(h[i][r+d-1]-h[i][r-1]*sum[d]%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;
}
int main(){
scanf("%d%d",&n,&t);
scanf("%s",s+1);
len=strlen(s+1);
Hash();
init();
for(int i=1;i<=t;i++){
int l,r,d;
scanf("%d%d%d",&l,&r,&d);
if(solve(l,r,d)) printf("YES\n");
else printf("NO\n");
}
return 0;
}