字符串哈希匹配字符串

字符串哈希匹配字符串

问题描述

这是一道模板题。

给定一个长度为 nn 仅由小写字母构成的字符串 SS,再给定 qq 组查询,每次查询给定 44 个整数 l1,r1,l2,r2l1​,r1​,l2​,r2​。你需要输出 Sl1∼r1Sl1​∼r1​​ 与 Sl2∼r2Sl2​∼r2​​ 是否相同。

输入格式

第一行输入两个正整数 n,qn,q。(1≤n,q≤2×105)(1≤n,q≤2×105)。

第二行输入一个字符串 SS。((a ≤Si≤≤Si​≤ z,1≤i≤n),1≤i≤n)。

接下来 qq 行每行输入 44 个正整数 l1,r1,l2,r2l1​,r1​,l2​,r2​。(1≤l1≤r1≤n,1≤l2≤r2≤n,r1−l1=r2−l2)(1≤l1​≤r1​≤n,1≤l2​≤r2​≤n,r1​−l1​=r2​−l2​)。

输出格式

输出 qq 行,对于每次查询,如果查询的两个字符串相同输出 Yes,否则输出 No

样例输入

复制代码
4 3
abbc
1 2 2 3
2 2 3 3
1 3 2 4

样例输出

复制代码
No
Yes
No

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int N = 2*100010,p=131;//改值减少冲突
    static int a[]=new int[N];
    static int b[]=new int[N];
    
    public static void main(String[] args) throws IOException {
    
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        int n=Integer.parseInt(br.readLine());
        String g[] = br.readLine().split(" ");
        int n=Integer.parseInt(g[0]),q=Integer.parseInt(g[1]);
        String string=br.readLine();
//        h[i]=h[i−1]×p+s[i], h[0]=0
//        		p:基数(通常取质数,如 (131、13331))
//        		(s[i]):字符串第 i 位字符的 ASCII 值(示例中 A=65,B=66,C=67)		
//        h[l,r]=h[r]−h[l−1]×p^(r−l+1)
        
        		
        b[0]=1;
        for (int i = 1; i <= n; i++) {
			b[i]=b[i-1]*p;
			a[i]=a[i-1]*p+string.charAt(i-1);
		}
        for (int i = 0; i <q; i++) {
        	g = br.readLine().split(" ");
        	int l1=Integer.parseInt(g[0]),r1=Integer.parseInt(g[1]);
        	int l2=Integer.parseInt(g[2]),r2=Integer.parseInt(g[3]);
        	if(getHash(l1, r1,string)==getHash(l2, r2,string)){
        		System.out.println("Yes");
        	}else{
        		System.out.println("No");
        	}
		}
    }
    static int getHash(int l,int r,String string){
    	return a[r]-a[l-1]*b[r-l+1];
    }
}

双哈希:

复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int N = 2*100010,p1=131,p2=13331,mod1=(int)(1e9)+7,mod2=(int)(1e9)+9;//改p值减少冲突
    static long a1[]=new long[N];//采用long
    static long b1[]=new long[N];
    static long a2[]=new long[N];
    static long b2[]=new long[N];
    
    public static void main(String[] args) throws IOException {
    	
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        int n=Integer.parseInt(br.readLine());
        String g[] = br.readLine().split(" ");
        int n=Integer.parseInt(g[0]),q=Integer.parseInt(g[1]);
        String string=br.readLine();
//        h[i]=h[i−1]×p+s[i], h[0]=0
//        		p:基数(通常取质数,如 (131、13331))
//        		(s[i]):字符串第 i 位字符的 ASCII 值(示例中 A=65,B=66,C=67)		
//        h[l,r]=h[r]−h[l−1]×p^(r−l+1)
        
        		
        b1[0]=1;
        for (int i = 1; i <= n; i++) {
			b1[i]=b1[i-1]*p1%mod1;
			a1[i]=(a1[i-1]*p1+string.charAt(i-1))%mod1;
		}
        b2[0]=1;
        for (int i = 1; i <= n; i++) {
			b2[i]=b2[i-1]*p2%mod2;
			a2[i]=(a2[i-1]*p2+string.charAt(i-1))%mod2;
		}
        for (int i = 0; i <q; i++) {
        	g = br.readLine().split(" ");
        	int l1=Integer.parseInt(g[0]),r1=Integer.parseInt(g[1]);
        	int l2=Integer.parseInt(g[2]),r2=Integer.parseInt(g[3]);
        	if(getHash1(l1, r1,string)==getHash1(l2, r2,string) &&
        	  getHash2(l1, r1,string)==getHash2(l2, r2,string)	
        	 ){
        		System.out.println("Yes");
        	}else{
        		System.out.println("No");
        	}
		}
    }
    static int getHash1(int l,int r,String string){
    	return (int)((a1[r]-a1[l-1]*b1[r-l+1])%mod1+mod1)%mod1;
    }
    static int getHash2(int l,int r,String string){
    	return (int)((a2[r]-a2[l-1]*b2[r-l+1])%mod2+mod2)%mod2;
    }
}
相关推荐
周末也要写八哥1 小时前
浅谈二叉树的深度优先搜索(DFS)算法
算法·深度优先
y = xⁿ1 小时前
20天速通LeetCodeday17:一维动态规划
算法
bnmoel1 小时前
数据结构深度剖析栈与队列:结构、边界实现与进出操作全解析
c语言·数据结构·算法··队列
WL_Aurora1 小时前
Python 算法基础篇之查找算法(一):顺序查找、二分查找与插值查找
开发语言·python·算法
ChoSeitaku2 小时前
06_可变参数_递归_类和对象_封装
java·数据结构·算法
-To be number.wan2 小时前
算法日记 | 动态规划(初级)
算法·动态规划
_深海凉_2 小时前
LeetCode热题100-二叉搜索树中第 K 小的元素
算法·leetcode·职场和发展
图码2 小时前
文本两端对齐算法详解:从LeetCode到实际应用
数据结构·图像处理·算法·leetcode·生成对抗网络·面试·职场和发展
liu****2 小时前
第16届国赛蓝桥杯大赛C/C++大学C组
c语言·数据结构·c++·算法·蓝桥杯