zoukankan      html  css  js  c++  java
  • CodeForces985F:Isomorphic Strings (字符串&hash)

    题意:取出字符串Str里的两个串S,T,问对应位置的的字符在否有一一映射关系。

    hash:对于每个字符s=‘a’-‘z’,我们任意找一个i,满足Si==s,(代码里用lower_bound在区间找到最小的位置i)其对应的字符为Ti==t。然后我们判断这段区间里s的hash值是否等于t的hash值。不难证明26个字母都满足时对应hash相同时,才有一一映射关系。(但是不明白我的自然溢出的hash版本为什么错了,但是mod(1e9+7)的版本对了?

    #include<bits/stdc++.h>
    using namespace std;
    #define ll unsigned long long
    const int maxn=200010;
    const int seed=131;
    const int Mod=1e9+7;
    ll Hash[26][maxn],g[maxn];
    int a[26][maxn],N;
    char c[maxn];
    ll gethash(int chr,int x,int Len)
    {
        return ((Hash[chr][x+Len-1]-Hash[chr][x-1]*g[Len]%Mod)+Mod)%Mod;
    }
    bool check(int x,int y,int Len)
    {
        int i,pos;
        for(i=0;i<26;i++){
            pos=lower_bound(a[i]+1,a[i]+1+a[i][0],x)-a[i];
            if(pos>a[i][0]||a[i][pos]>x+Len-1) continue;
            if(gethash(i,x,Len)!=gethash(c[y-x+a[i][pos]]-'a',y,Len))  return false;
        }
        return true;
    }
    int main()
    {
        int Q,x,y,len,i,j;
        scanf("%d%d",&N,&Q);
        scanf("%s",c+1); g[0]=1;
        for(i=1;i<=N;i++){
            g[i]=g[i-1]*seed%Mod;
            for(j=0;j<26;j++) 
               Hash[j][i]=(Hash[j][i-1]*seed+(c[i]-'a'==j))%Mod;        
            a[c[i]-'a'][++a[c[i]-'a'][0]]=i;
        }
        while(Q--){
            scanf("%d%d%d",&x,&y,&len);
            if(check(x,y,len)) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }

    下面是自然溢出的has版本

    #include<bits/stdc++.h>
    using namespace std;
    #define ll unsigned long long
    const int maxn=200010;
    const int seed=131;
    ll Hash[26][maxn],g[maxn];
    int a[26][maxn],N;
    char c[maxn];
    ll gethash(int chr,int x,int Len)
    {
        return Hash[chr][x+Len-1]-Hash[chr][x-1]*g[Len];
    }
    bool check(int x,int y,int Len)
    {
        int i,pos;
        for(i=0;i<26;i++){
            pos=lower_bound(a[i]+1,a[i]+1+a[i][0],x)-a[i];
            if(pos>a[i][0]||a[i][pos]>x+Len-1) continue;
            if(gethash(i,x,Len)!=gethash(c[y-x+a[i][pos]]-'a',y,Len))  return false; 
        }
        return true;
    }
    int main()
    {
        int Q,x,y,len,i,j;
        scanf("%d%d",&N,&Q);
        scanf("%s",c+1); g[0]=1;
        for(i=1;i<=N;i++){
            g[i]=g[i-1]*seed;
            for(j=0;j<26;j++) 
               Hash[j][i]=Hash[j][i-1]*seed+(c[i]-'a'==j);        
            a[c[i]-'a'][++a[c[i]-'a'][0]]=i;
        }
        while(Q--){
            scanf("%d%d%d",&x,&y,&len);
            if(check(x,y,len)) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    第七十天 how can I 坚持
    第六十九天 how can I 坚持
    第六十八天 how can I 坚持
    第六十七天 how can I 坚持 (补昨天)
    第六十六天 how can I 坚持··
    第六十五天 how can I 坚持
    第六十四天 how can i 坚持
    第六十三天 how can I 坚持
    MyEclipse10 中的两种FreeMarker插件的安装与配置
    画板社交工具开发分享——HTML5 canvas控件、PHP、社交分享学习(四)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9074020.html
Copyright © 2011-2022 走看看