双Hash--兔子与兔子
Posted cutemush
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双Hash--兔子与兔子相关的知识,希望对你有一定的参考价值。
很久很久以前,森林里住着一群兔子。
有一天,兔子们想要研究自己的DNA序列。
我们首先选取一个好长好长的DNA序列(小兔子是外星生物,DNA序列可能包含26个小写英文字母)。
然后我们每次选择两个区间,询问如果用两个区间里的DNA序列分别生产出来两只兔子,这两个兔子是否一模一样。
注意两个兔子一模一样只可能是他们的DNA序列一模一样。
Input
第一行输入一个DNA字符串S。
第二行一个数字m,表示m次询问。
接下来m行,每行四个数字l1,r1,l2,r2,分别表示此次询问的两个区间,注意字符串的位置从1开始编号。
数据范围
1≤length(S),m≤1000000
Output
对于每次询问,输出一行表示结果。
如果两只兔子完全相同输出Yes,否则输出No(注意大小写)。
Sample Input
aabbaabb
3
1 3 5 7
1 3 6 8
1 2 1 2
Sample Output
Yes
No
Yes?
#include<bits/stdc++.h> using namespace std; #define maxn 1000005 typedef long long ll; //typedef long double ld; int n,m; char s[maxn]; inline int read() { int x=0,f=1; char ch=getchar(); for (;ch<‘0‘||ch>‘9‘;ch=getchar()) if (ch==‘-‘) f=-1; for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; return x*f; } struct hash_table { int mod,base,power[maxn],h[maxn]; void build() { for (int i=1;i<=n;i++) h[i]=1ll*h[i-1]*base%mod+s[i]-‘a‘; power[0]=1; for (int i=1;i<=n;i++) power[i]=1ll*power[i-1]*base%mod; } bool check(int l1,int r1,int l2,int r2) { int len=r1-l1+1; int h1=((h[r1]-1ll*h[l1-1]*power[len]%mod)+mod)%mod; int h2=((h[r2]-1ll*h[l2-1]*power[len]%mod)+mod)%mod; return h1==h2; } }H1,H2; int main() { H1.mod=998244353,H2.mod=666623333; H1.base=233,H2.base=431; scanf("%s",s+1); n=strlen(s+1); H1.build(),H2.build(); int id=0; for (int T=read();T;T--) { ++id; int l1=read(),r1=read(),l2=read(),r2=read(); if (r1-l1+1!=r2-l2+1) { puts("No"); continue; } puts((H1.check(l1,r1,l2,r2)&&H2.check(l1,r1,l2,r2))?"Yes":"No"); } return 0; }
单Hash
//19260817 #include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int MAX=1000010; int mod=19260817; int n,length,q; int l1,r1,l2,r2; char a[MAX]; ull sum[MAX]; ull prime=131; ull power[MAX]; ull cut(int l,int r) { return ((sum[r]-sum[l-1]*power[r-l+1])%mod+mod)%mod; } int main() { scanf("%s",a+1); scanf("%d",&q); int num=strlen(a+1); power[0]=1; sum[0]=0; for(int i=1; i<=1000000; i++) power[i]=(power[i-1]*prime)%mod; for(int i=1; i<=num; i++) sum[i]=(sum[i-1]*prime+a[i]-‘a‘)%mod; while(q--) { scanf("%d%d%d%d",&l1,&r1,&l2,&r2); if(l1-r1!=l2-r2) { puts("No"); continue; } if(cut(l1, r1)==cut(l2, r2))puts("Yes"); else puts("No"); } return 0; }
以上是关于双Hash--兔子与兔子的主要内容,如果未能解决你的问题,请参考以下文章