码迷,mamicode.com
首页 > 其他好文 > 详细

兔子与兔子(字符串Hash)

时间:2019-07-09 22:33:48      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:sign   scan   一模一样   iostream   ash   string   put   sig   区间   

描述

很久很久以前,森林里住着一群兔子。有一天,兔子们想要研究自己的 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

Solution

有趣的Hash呀!
可以维护整个字符串所有前缀的hash值F[i],然后计算子串(づ ●─● )づ


Code

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

const int N = 1000007, P = 131;
char s[N];
int n, m, l1, l2, r1, r2, len1, len2;
unsigned long long f[N], p[N]; 

inline int read(){
    int ans = 0, f = 1;
    char ch = getchar();
    for(; ch < '0' || ch > '9'; ch = getchar())
        if (ch == '-')
            f = 0;
    for(; ch >= '0' && ch <= '9'; ch = getchar())
        ans = (ans << 3) + (ans << 1) + ch - 48;
    return f? ans: -ans;
}

int main(){
    scanf("%s", s + 1);
    n = strlen(s + 1);
    p[0] = 1;
    for (int i = 1; i <= n; ++i){
        f[i] = f[i - 1] * P + s[i] - 'a' + 1;
        p[i] = p[i - 1] * P;
    }
    m = read();
    while (m--){
        l1 = read(), r1 = read(), l2 = read(), r2 = read();
        len1 = r1 - l1 + 1, len2 = r2 - l2 + 1; 
        if (f[r1] - f[l1 - 1] * p[len1] == f[r2] - f[l2 - 1] * p[len2])
            puts("Yes"); else
            puts("No");
    } 
    
    return 0;
}

兔子与兔子(字符串Hash)

标签:sign   scan   一模一样   iostream   ash   string   put   sig   区间   

原文地址:https://www.cnblogs.com/DorkyTAT/p/11160653.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!