Codeforces 1320 D Reachable Strings —— 哈希,不能自动取模?

This way

题意:

给你一个01串,你只有两种操作:将某个位置的011变成110或者将某个位置的110变成011.
每次问你两个区间的子串能否相互转换。

题解:

这就是说0能够通过偶数个1转移到另一个位置,也就是两个0如果中间有奇数个1,那么就是说这是两个区间的0.

h[1][i].first=(h[1][i-1].first*23ll+(i&1)+1)%mod;

那么这样子哈希也就是区分了奇偶的位置,也就是说这是奇偶性的哈希而不是通常那样的按位置哈希。(这么优秀的算法一看就不是我自己想的)
为什么有两个哈希数组是因为,要看第一个0前面有多少个1.
但是不知道为什么自动取模一直过不了,我加个取模就过了,可能都不需要双哈希。

#include<bits/stdc++.h>
using namespace std;
#define ull long long
#define pa pair<ull,ull>
const int N=3e5+5;
const ull mod=1e9+7;
pa h[2][N],p[N];
int cnt[N];
char s[N];
pa get_h(int l,int r){
    ull h1=(h[l&1][r].first-h[l&1][l-1].first*p[cnt[r]-cnt[l-1]].first%mod+mod)%mod;
    ull h2=(h[l&1][r].second-h[l&1][l-1].second*p[cnt[r]-cnt[l-1]].second%mod+mod)%mod;
    return {h1,h2};
}
int main()
{
    int n;
    scanf("%d%s",&n,s+1);
    p[0]={1,1};
    for(int i=1;i<=n;i++){
        p[i].first=p[i-1].first*23ll%mod;
        p[i].second=p[i-1].second*131ll%mod;
        cnt[i]=cnt[i-1]+(s[i]=='0');
        if(s[i]=='0'){
            h[0][i].first=(h[0][i-1].first*23ll+((i&1)^1)+1)%mod;
            h[0][i].second=(h[0][i-1].second*131ll+((i&1)^1)+1)%mod;
            h[1][i].first=(h[1][i-1].first*23ll+(i&1)+1)%mod;
            h[1][i].second=(h[1][i-1].second*131ll+(i&1)+1)%mod;
        }
        else
            h[0][i]=h[0][i-1],h[1][i]=h[1][i-1];
    }
    int q;
    scanf("%d",&q);
    while(q--){
        int p1,p2,l;
        scanf("%d%d%d",&p1,&p2,&l);
        pa h1=get_h(p1,p1+l-1),h2=get_h(p2,p2+l-1);
        if(h1.first==h2.first&&h1.second==h2.second)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

发布了584 篇原创文章 · 获赞 33 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/105174321