题目链接
题目
输入一个字符串s,然后有q个询问。每次询问有 l1, r1, l2, r2,分别表示此次询问的两个区间, 如果两个区间一模一样的话输出Yes,否则输出No。
题解
取一固定值P,把字符串看作P进制数,然后取一固定值M(2^64),求出该P进制数对M的余数,作为字符串的哈希值。
注意,取模可以通过ull的溢出来实现。
用一个例子来介绍字符串哈希。
假设S=‘abc’, c=‘d', T=‘xyz’,则:S 表示的 P进制数为123
S+T 表示的P进制数 : 1 2 3 24 25 26
S在P进制下左移lenth(T)位 : 1 2 3 0 0 0
二者相减就是T表示的P进制数: 24 25 26
预处理O(n),查询O(1)。
代码
int n,m;
ull f[maxn],p[maxn];
string s;
bool check(int a,int b,int c,int d) {
if(f[b]-f[a]*p[b-a+1]==f[d]-f[c]*p[d-c+1]) return true;
return false;
}
int main()
{
cin>>s>>m;
p[0] = 1;
for(int i=1;i<=s.length();i++) {
f[i] = f[i-1]*131+(s[i-1]-'a'+1);
p[i] = p[i-1]*131;
}
for(int i=0;i<m;i++) {
int l1,r1,l2,r2;
read(l1),read(r1),read(l2),read(r2);
if(check(l1,r1,l2,r2)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}