Codeforces 985F-Isomorphic Strings

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;
} 

猜你喜欢

转载自www.cnblogs.com/qjy73/p/12498089.html
今日推荐