题意简述:给定一个长度为n(n<=2e5)的字符串S(仅含有小写字母),有m(m<=2e5)次查询。每次查询给三个数,x,y,len,求在S[x]~S[x+len-1]和S[y]~S[y+len-1]是否存在相应位置唯一对应关系。(例如aba和brb,aaa和kkk,abs和ert是唯一对应。aab和abc,test和best则不是唯一对应)
分析:此题比较次数比较多,可采用哈希字符串来解决。由于比较的是字符相应位置,可对S串中每个字符分别哈希。然后对于两个字串,就可以逐一求出每个字符的哈希值,然后就是求26个字符的逐一对应关系,排个序就解决啦。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const int N=2e5+10;
LL h[26][N],p[N];
int a[30],b[30];
char s[N+10];
LL get(int i,int l,int r)
{
return h[i][r]-h[i][l-1]*p[r-l+1];
}
int main()
{
int n,m,x,y,len;
while(scanf("%d%d",&n,&m)!=EOF)
{
p[0]=1;
for(int i=1;i<=n;i++)p[i]=p[i-1]*7;
scanf(" %s",s+1);
for(int i=0;i<26;i++)
for(int j=1;j<=n;j++)
h[i][j]=h[i][j-1]*7+(s[j]=='a'+i)*3;
while(m--)
{
scanf("%d%d%d",&x,&y,&len);
for(int i=0;i<26;i++)
{
a[i]=get(i,x,x+len-1);
b[i]=get(i,y,y+len-1);
}
sort(a,a+26);
sort(b,b+26);
bool flag=true;
for(int i=0;i<26;i++)
if(a[i]!=b[i])
{
flag=false;
break;
}
printf("%s\n",flag?"YES":"NO");
}
}
}