码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces985F:Isomorphic Strings (字符串&hash)

时间:2018-05-22 22:17:01      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:bsp   closed   iso   code   long   false   mes   pac   one   

题意:取出字符串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\n");
        else printf("NO\n");
    }
    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\n");
        else printf("NO\n");
    }
    return 0;
}
View Code

 

 

 

 

#include<bits/stdc++.h>using namespace std;#define ll unsigned long longconst 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\n");else printf("NO\n");}return 0;}

 

CodeForces985F:Isomorphic Strings (字符串&hash)

标签:bsp   closed   iso   code   long   false   mes   pac   one   

原文地址:https://www.cnblogs.com/hua-dong/p/9074020.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!