CF985F Isomorphic Strings

CF985F Isomorphic Strings

我们只需要把每个字符对应成 \(01\) 串就行了, \(0\) 代表当前位置不是这个字符, \(1\) 代表是, 然后求一遍 \(Hash\) , 每次 \(get\) 然后 \(sort\) , 判断两段是否相等即可.

\(code:\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
const int N = 2e5 + 5;
ll mod = 1e9 + 7, base = 29;
char s[N];
struct Hash {
    ll Hash[N][30], pw[N], s1[30], s2[30];
    void hs(char *s) {
        int len = strlen(s + 1);
        pw[0] = 1;
        for (int i = 1; i <= len; i++) {
            for (int j = 1; j <= 26; j++) {
                Hash[i][j] = Hash[i - 1][j] * base;
                if (j == s[i] - 'a' + 1) Hash[i][j]++;
                Hash[i][j] %= mod;
            }
            pw[i] = pw[i - 1] * base % mod;
        }
    }
    void Get(ll *s, int l, int r)  {
        for (int i = 1; i <= 26; i++) s[i] = ((Hash[r][i] - Hash[l - 1][i] * pw[r - l + 1]) % mod + mod) % mod;
        sort(s + 1, s + 27);
    }
    bool Judge(int l, int r, int len) {
        Get(s1, l, l + len - 1);
        Get(s2, r, r + len - 1);
        for (int i = 1; i <= 26; i++) {
            if (s1[i] != s2[i]) return false;
        }
        return true;
    }
} S;
int n, m;
int main() {
    srand(time(NULL));
    mod += rand(), base += rand() % 10;
    n = read(), m = read();
    scanf("%s", s + 1);
    S.hs(s);
    for (; m; m--) {
        int l = read(), r = read(), len = read();
        if (S.Judge(l, r, len)) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
posted @ 2021-09-03 15:46  sshadows  阅读(31)  评论(0编辑  收藏  举报