兔子的兔子(字符串hash)
把我坑惨了(1个小时) 将cin
换成scanf
cout
换成printf
就过了,
思路:询问区间值就用前缀和来做,将字符串通过一个hash函数映射在几乎不会重复的集合内,能够快速判断是否子字符串是否重复出现过,
- 用
unsigned long long
存hash值相当于自动对$2^{64}$mod - 把字符串看成P进制下的数,如
S="abc"
$h(S)=1p^2+2p^1+3*p^0$ - 在S后添加一个
char
c $h(s+c)=h(s)*p+(c-‘a’+1)$同理char c
换成string
- $h(s+t)=h(s)*p^{t.size()}+h(t)$ 就是进制进位计算,理解很简单
- 注意 计算区间子串hash值时,保证p进制的位是相同的然后在相减。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=1000005;
char str[maxn];
unsigned long long sum[maxn],f[maxn];
int main(){
freopen("a.txt","r",stdin);
scanf("%s",str+1);
int len=strlen(str+1);
int m;
scanf("%d",&m);
f[0]=1;
for(int i=1;i<=len;i++){
sum[i]=sum[i-1]*131+(str[i]-'a'+1);
f[i]=131*f[i-1];
}
for(int i=1;i<=m;i++){
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d);
if( sum[b]-sum[a-1]*f[b-a+1] == sum[d]-sum[c-1]*f[d-c+1]) printf("Yes\n");
else printf("No\n");
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!