【字符串hash】 Isomorphic Strings
题目大意:
给定一个母串,然后让你判断指定两个区间的字符子串是否存在字母之间相互映射的关系。
解题分析:
因为有$m$次询问,所以先预处理一下母串的信息,将母串上的字符用26个01串维护(每个01串对应每个字母在母串中的存在情况),并且计算每个01串的hash值,然后每次询问,对于每个字符串指定的两个区间计算对应26个字母的hash值,比较一下这26个hash值是否重排后相等即可(可以先统一sort之后再一一比较)。#includeusing namespace std;const int N = 2e5+5 , MOD = 1e9+7;int hs[26][N],val1[30],val2[30],pw[N];char s[N];inline int GetHash(int id,int l,int len){ //得到指定区间的hash值,因为字符串hash时是左边的权值更低 int r=l+len-1; return (hs[id][r]-1ll*hs[id][l-1]*pw[len])%MOD;}int main(){ int n,m;cin>>n>>m; scanf("%s",s+1); for(int i=0;i<26;i++) for(int j=1;j<=n;j++){ hs[i][j]=((s[j]==(char)('a'+i))+hs[i][j-1]*2)%MOD; } //得到母串的26个字母对应的01串的hash值(二进制hash) pw[0]=1;for(int i=1;i<=n;i++)pw[i]=(pw[i-1]<<1)%MOD; while(m--){ int l1,l2,len;scanf("%d%d%d",&l1,&l2,&len); for(int i=0;i<26;i++) //得到指定区间内的26个字母的hash情况 val1[i]=(GetHash(i,l1,len)+MOD)%MOD,val2[i]=(GetHash(i,l2,len)+MOD)%MOD; sort(val1,val1+26);sort(val2,val2+26); //进行重排 bool fp=true; for(int i=0;i<26;i++) if(val1[i]!=val2[i]) { fp=false;break; } fp?puts("YES"):puts("NO"); }}