1. 程式人生 > 實用技巧 >841.字串雜湊

841.字串雜湊

給定一個長度為n的字串,再給定m個詢問,每個詢問包含四個整數l1,r1,l2,r2,請你判斷[l1,r1]和[l2,r2]這兩個區間所包含的字串子串是否完全相同。
字串中只包含大小寫英文字母和數字。

輸入格式

第一行包含整數n和m,表示字串長度和詢問次數。
第二行包含一個長度為n的字串,字串中只包含大小寫英文字母和數字。
接下來m行,每行包含四個整數l1,r1,l2,r2
,表示一次詢問所涉及的兩個區間。
注意,字串的位置從1開始編號。

輸出格式

對於每個詢問輸出一個結果,如果兩個字串子串完全相同則輸出“Yes”,否則輸出“No”。
每個結果佔一行。

資料範圍

1≤n,m≤105

輸入樣例:

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

輸出樣例:

Yes
No
Yes

參考程式碼

import java.util.Scanner;

public class Main {

	static long ULL = (long) Math.pow(2, 64);
	static int N = 100010;
	static int P = 131;
	static long[] h = new long[N];
	static long[] p = new long[N];

	public static long get(int l, int r) {
		return h[r] - h[l - 1] * p[r - l + 1] % ULL;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();
		int m = sc.nextInt();
		sc.nextLine();
		String str = sc.nextLine();

		p[0] = 1;
		for (int i = 1; i <= n; i++) {
			p[i] = p[i - 1] * P % ULL;
			h[i] = (h[i - 1] * P % ULL + str.charAt(i-1)) % ULL;
		}

		while ((m--) != 0) {
			int l1 = sc.nextInt();
			int r1 = sc.nextInt();
			int l2 = sc.nextInt();
			int r2 = sc.nextInt();

			if (get(l1, r1) == get(l2, r2)) {
				System.out.println("Yes");
			} else {
				System.out.println("No");
			}

		}

		sc.close();
	}
}