Hihocoder 挑戰賽17 String Problem I (字符串HASH)

分析:第一次寫字符串hash,學習的AC代碼的寫法。

其實就是把字符串變成一個p1進制的數(Mod1),由於有衝突:所以用兩種方法表示:p2進制的數。

此題需要注意的點:原串中掃一遍去掉一個點時,如果相鄰的兩個點一樣,那麼去掉以後效果是一樣的,這種情況只要算一遍。

代碼:

#include <bits/stdc++.h>

using namespace std;

#define FOR(i,x,y)  for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define pb  push_back
#define mp  make_pair
#define fi  first
#define se  second
#define sc(x)       scanf("%d",&x)
#define sc2(x,y)    scanf("%d%d",&x,&y)
#define sc3(x,y,z)  scanf("%d%d%d",&x,&y,&z)
typedef long long LL;
typedef vector <int>    VI;
typedef pair <int,int>  PII;

const int maxn = 100010;
const int p1= 17,p2 = 19,Mod1 = 1e9+7,Mod2 = 1e9+9;

map <PII,int> hs;

LL h1[maxn],h2[maxn],f1[maxn],f2[maxn];
char str[maxn];
int n,m;

PII geths(int l,int r){
    if(l == 0)  return mp(f1[r],f2[r]);
    if(l > r)   return mp(0,0);
    return mp((f1[r]-f1[l-1]*h1[r-l+1]%Mod1+Mod1)%Mod1,
            (f2[r]-f2[l-1]*h2[r-l+1]%Mod2+Mod2)%Mod2);
}

int main(){
    //freopen("in.txt","r",stdin);
    h1[0] = h2[0] = 1;
    FOR(i,1,maxn)   h1[i] = h1[i-1]*p1%Mod1,h2[i] = h2[i-1]*p2%Mod2;
    sc2(n,m);
    FOR(i,0,n){
        scanf("%s",str);    
        int len = strlen(str);
        f1[0] = f2[0] = str[0]-'a';
        FOR(j,1,len){
            f1[j] = (f1[j-1]*p1%Mod1+str[j]-'a')%Mod1;
            f2[j] = (f2[j-1]*p2%Mod2+str[j]-'a')%Mod2;
        }
        hs[mp((f1[len-1]-h1[len-1]*f1[0]%Mod1+Mod1)%Mod1,
                (f2[len-1]-h2[len-1]*f2[0]%Mod2+Mod2)%Mod2)] ++;
        FOR(j,1,len){
            if(str[j] == str[j-1])  continue;
            PII x = geths(0,j-1),y = geths(j+1,len-1);
            hs[mp((x.fi*h1[len-1-j]%Mod1+y.fi)%Mod1,
                    (x.se*h2[len-1-j]%Mod2+y.se)%Mod2)] ++;
        }
    }
    FOR(i,0,m){
        scanf("%s",str);
        int len = strlen(str);
        LL sum1,sum2;
        sum1 = sum2 = str[0]-'a';
        FOR(j,1,len){
            sum1 = (sum1*p1%Mod1+str[j]-'a')%Mod1;
            sum2 = (sum2*p2%Mod2+str[j]-'a')%Mod2;
        }
        printf("%d\n",hs[mp(sum1,sum2)]);
    }
    return 0;
}
發佈了157 篇原創文章 · 獲贊 13 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章