codeforces 985 F. Isomorphic Strings

标签: 字符串hash


题目链接

https://codeforces.com/contest/985/problem/F

题意

首先定义两个长度相等字符串a,b同构,当且仅当a中的每个字母,b中只存在一个字母与之对应,并且两个字母出现位置要完全一致,a,b反过来也要满足。
给定一个长度为\(2 \times 10^5\)的字符串s,有很多次询问。每次询问s从x位置开始的长度为l的字串与从y开始的长度为l的字串是否同构。

分析

对每个字母出现位置的集合进行哈希。
比如对于字母\('k'\),我们把原串中出现\('k'\)的位置用1替代,其他用0替代。求出新产生的01串的哈希,这样01串某个字串的哈希其实就代表着\('k'\)在这个字串中出现位置的集合。
(据说自然溢出会wa)

代码

#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=200050;
const ll MOD=1e9+7;
ll h[26][maxn],x=107,px[maxn];
char s[maxn];
int main(){
    int n,m;
    scanf("%d%d", &n,&m);
    scanf("%s", s+1);
    px[0]=1;
    for(int i = 1; i <= n; ++i) px[i]=px[i-1]*x%MOD;
    for(int i = 0; i < 26; ++i){
        for(int j = 1; j <= n; ++j){
            h[i][j]=(h[i][j-1]*x+int(s[j]==i+'a'))%MOD;
        }
    }
    while(m--){
        int x,y,l;
        scanf("%d%d%d", &x,&y,&l);
        vector<int> p,q;
        for(int i = 0; i < 26; ++i){
            p.push_back(((h[i][x+l-1]-px[l]*h[i][x-1]%MOD)%MOD+MOD)%MOD);
            q.push_back(((h[i][y+l-1]-px[l]*h[i][y-1]%MOD)%MOD+MOD)%MOD);
        }
        sort(q.begin(),q.end());
        sort(p.begin(),p.end());
        printf("%s\n", p==q?"YES":"NO");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sciorz/p/9092648.html
今日推荐