hdu 1381

題意:

判斷字符串中有多少個長度爲N的子串,且字符總類不會超過NC種。


解題思路:

字符串hash


注意:

//字符串hash
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <set>
#include <math.h>
using namespace std;
typedef long long LL;
#define MAXSZ 1700000
#define MOD 1000003
set<LL> st;
set<LL>::iterator itr;
char str[MAXSZ];
int N,NC;
void clear(){
    if(st.size()){
        st.clear();
    }
}
inline LL BKDRHash(char *str)
{
    LL seed = 31; // 31 131 1313 13131  etc..
    LL hash = 0;
    
    while (*str)
    {
        hash = hash * seed + (*str++);
    }
    
    return (hash /*& 0x7FFFFFFF*/);
}
int solve(char *s){
    int ans = 1;
    char *p0  = s,*p1 = s+N;
    LL hash = 0,tmp,hash1 = 1;
    LL seed = 31;
    char cc = (*p1);
    (*p1) = 0;
    hash = BKDRHash(p0);
    (*p1) = cc;
    tmp = hash&0x7FFFFFFF;
    st.insert(tmp);
    for(int i=1;i<N;++i){
        hash1*=seed;
    }
    while((*p1)){
        hash = hash - hash1*(*p0);
        //++p1;
        
        hash = hash*seed + (*p1);
        tmp = hash&0x7FFFFFFF;
        itr = st.find(tmp);
        if(itr==st.end()){
            st.insert(tmp);
            ++ans;
        }
        //        if(!st.count(tmp)){
        //            st.insert(tmp);
        //            ans++;
        //        }
        ++p1;
        ++p0;
        
    }
    return ans;
}
int main(){
    int T;
    //        for(int i=1000000;;i++){
    //            bool flag = true;
    //            for(int j=2;j<=sqrt(i*1.0);j++){
    //                if(i%j==0){
    //                    flag = false;
    //                    break;
    //                }
    //                }
    //                if(flag){
    //                    printf("%d\n",i);
    //                break;
    //        }
    //}
    
    
    
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&NC);
        scanf("%s",str);
        int ans =  solve(str);
        printf("%d\n",ans);
        clear();
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章