CH1401 兔子与兔子(Hash)

题意

在一个字符串中,请判断字符串[l1,r1]与[l2,r2]是否相同。

题解

Hash
判断相同?正是用hash的地方!
我们用前缀的形式求出[1,i]的hash值。\small hash[1,i]=hash[1,i-1]*P+s[i]-'a',其实就是把字符串看成一个P进制的数(P这里取了131)。
如果要求[l,r]的hash值,我们可以用hash[1,r]减去hash[1,l-1]。因为在变到hash[l,r]中,hash[1,l-1]乘了P^(r-l-1),所以要把hash[1,l-1]左移r-l-1位,再与hash[1,r]做差。\small hash[l,r]=hash[1,r]-hash[1,l-1]*P^{r-l-1}

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const int maxn=1000010;
const ull P=131;ull power[maxn];//power[i]=P^i

char s[maxn];
ull h[maxn];

ull calc(int l,int r)
{
    return h[r]-h[l-1]*power[r-(l-1)];
}

int main()
{
    power[0]=1;
    for(int i=1;i<=1000000;i++) power[i]=power[i-1]*P;
    scanf("%s",s+1);
    int n=strlen(s+1);
    for(int i=1;i<=n;i++) h[i]=h[i-1]*P+s[i]-'a';
    int T;scanf("%d",&T);
    while(T--)
    {
        int l1,r1,l2,r2;
        scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
        if(l1-r1!=l2-r2){puts("No");continue;}
        if(l1>l2) swap(l1,l2),swap(r1,r2);
        if(calc(l1,r1)==calc(l2,r2)) puts("Yes");
        else puts("No");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/A_Bright_CH/article/details/81515148