CH 1401兔子与兔子

版权声明:本文为博主原创文章,记录蒟蒻的成长之路,欢迎吐槽~ https://blog.csdn.net/PegasiTIO/article/details/89402156

描述

很久很久以前,森林里住着一群兔子。有一天,兔子们想要研究自己的 DNA 序列。我们首先选取一个好长好长的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 个小写英文字母),然后我们每次选择两个区间,询问如果用两个区间里的 DNA 序列分别生产出来两只兔子,这两个兔子是否一模一样。注意两个兔子一模一样只可能是他们的 DNA 序列一模一样。

输入格式

第一行一个 DNA 字符串 S。
接下来一个数字 m,表示 m 次询问。
接下来 m 行,每行四个数字 l1, r1, l2, r2,分别表示此次询问的两个区间,注意字符串的位置从1开始编号。
其中 1 ≤ length(S), m ≤ 1000000

输出格式

对于每次询问,输出一行表示结果。如果两只兔子完全相同输出 Yes,否则输出 No(注意大小写)

样例输入

aabbaabb
3
1 3 5 7
1 3 6 8
1 2 1 2

样例输出

Yes
No
Yes

字符串哈希

把字符串转化为131进制,另字母a - z = 1 - 26,分配时要分配大于0的数字

已知S的哈希值为Hash(S),那么在后面加一个字母c的哈希值为:

Hash(S + c) = Hash(S) + c - 'a' + 1最后加一是因为我们定义字母表示从1开始

已知S的哈希值为Hash(S)S + H的哈希值为Hash(S + H),那么Hash(H)的哈希值为:

Hash(H) = Hash(S + H) - Hash(S) * 131 ^ (length(H))最后乘是要把S + H的左端和S的左端对齐

p进制下,把一个数左移k位相当于对这个数乘p^k

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

using ull = unsigned long long;
const int maxn = 1000005;
ull Hash[maxn], p[maxn];//保存哈希值,保存幂次值
char s[maxn];

int main()
{
    scanf("%s", s + 1);
    int len = strlen(s + 1);
    p[0] = 1; //131^0

    for (int i = 1; i <= len; ++i)
    {
        Hash[i] = Hash[i - 1] * 131 + (s[i] - 'a' + 1);
        p[i] = p[i - 1] * 131;
    }

    int k, l1, r1, l2, r2;
    scanf("%d", &k);
    while (k--)
    {
        scanf("%d %d %d %d", &l1, &r1, &l2, &r2);
        if (Hash[r1] - Hash[l1 - 1] * p[r1 - l1 + 1] == //l1 - r1的哈希值
            Hash[r2] - Hash[l2 - 1] * p[r2 - l2 + 1])	//l2 - r2的哈希值
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/PegasiTIO/article/details/89402156