題目描述
很久很久以前,森林裡住著一群兔子。
有一天,兔子們想要研究自己的 DNA 序列。
我們首先選取一個好長好長的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 個小寫英文字母)。
然後我們每次選擇兩個區間,詢問如果用兩個區間裡的 DNA 序列分別生產出來兩隻兔子,這兩個兔子是否一模一樣。
注意兩個兔子一模一樣只可能是他們的 DNA 序列一模一樣。
輸入格式
第一行輸入一個 DNA 字串 S。
第二行一個數字 m,表示 m 次詢問。
接下來 m 行,每行四個數字 l1,r1,l2,r2,分別表示此次詢問的兩個區間,注意字串的位置從 1 開始編號。
輸出格式
對於每次詢問,輸出一行表示結果。
如果兩隻兔子完全相同輸出 Yes
,否則輸出 No
(注意大小寫)。
輸入輸出樣例
輸入 #1
aabbaabb
3
1 3 5 7
1 3 6 8
1 2 1 2
輸出 #1
Yes
No
Yes
說明/提示
資料保證,1≤∣S∣,m≤1000000。其中,∣S∣ 為字串 S 的長度。
首先我們應該瞭解 HASH是一種對映關係 ,其中一個鍵對應一個值
我們設計一個HASH儲存表,根據經驗 131是一個比較好的值避免雜湊衝突
其中 hs[i] = hs[i - 1] * 113 + s[i]; 相當於指讓hs[i - 1]位置左移
其中pw作用在於對其 如下例: 我們求尖括號的內容
C++ Code Example
#include<bits/stdc++.h>
using namespace std;
string s;
int q;
unsigned long long hs[1000005];
unsigned long long pw[1000005];
unsigned long long get_sizeHash(int a, int b) {
return hs[b] - hs[a - 1] * pw[b - a + 1];
}
int main() {
cin >> s;
s = " " + s;
pw[0] = 1;
for (int i = 1;i < s.size();i++) {
hs[i] = hs[i - 1] * 113 + s[i];
pw[i] = pw[i - 1] * 113;
}
cin >> q;
while (q--) {
int a, b, x, y;
cin >> a >> b >> x >> y;
if (get_sizeHash(a, b) == get_sizeHash(x, y)) cout << "Yes"<<endl;
else cout << "No"<<endl;
}
return 0;
}