单词检索——题解

呃の,这题,真的不想说话。。

题目大意

给出N个由小写字母组成的字符串,统计至少在M个字符串中出现过的长度为L的字符串数
N , M <= 2000 , L i , L <= 1000

一看,就知道是哈希——
对于每个长度为L的串,都哈希一下——还要记得 O ( 1 ) 推下一个哈希值,对于同一个模板中出现多次的字符串要记得去重

然后。。不要跟我说什么字符串哈希27进制更稳。。也不要说什么双大质数模数不会被卡。。反正我华丽丽地 W A 了一片,40分!

拼了命凑了一下午,生无可恋。。只能抄标程模数+26进制。。

只想说, 10 07 绝对不是个好哈希模数!!!

PS:不想写哈希表, s o r t ( ) + u n i q u e ( ) 水过。。
上“凄凄惨惨戚戚”的代码:

#pragma GCC optimize(6) 
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
const LL P1=499999999999993,P2=999973,PP=26;
int n,m,L,ans,T[2005];char s[1005];LL pow[2][1005];
struct ff{
    LL a,b;
    bool operator <(const ff y)const{return a<y.a||(a==y.a&&b<y.b);}
    bool operator ==(const ff y)const{return a==y.a&&b==y.b;}
    void clear(){a=b=0;}
}now,hsh[1005],all[2000005];
char gt(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
} 
int read(){
    int ret=0;char ch=gt();
    while(ch<'0'||ch>'9') ch=gt();
    while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt();
    return ret;
}
int main(){
    n=read(),m=read(),L=read();
    pow[0][0]=pow[1][0]=1;
    for(int i=1;i<=L;i++) pow[0][i]=pow[0][i-1]*PP%P1,pow[1][i]=pow[1][i-1]*PP%P2; //在Mod意义下的预处理
    for(int j=1;j<=n;j++){
        char ch=gt();int len=0;
        while(ch<'a'||ch>'z') ch=gt();
        while(ch>='a'&&ch<='z') s[++len]=ch-'a',ch=gt();
        if(len<L) continue;
        now.clear();
        for(int i=1;i<L;i++) now.a=(now.a*PP+s[i])%P1,now.b=(now.b*PP+s[i])%P2;
        for(int i=L;i<=len;i++){
            now.a=((now.a-pow[0][L-1]*s[i-L])%P1+P1)%P1,now.b=((now.b-pow[1][L-1]*s[i-L])%P2+P2)%P2;
            now.a=(now.a*PP+s[i])%P1,now.b=(now.b*PP+s[i])%P2;
            hsh[++T[j]]=now;
        }
        sort(hsh+1,hsh+1+T[j]),T[j]=unique(hsh+1,hsh+1+T[j])-hsh-1;
        for(int i=1;i<=T[j];i++) all[++T[0]]=hsh[i];
    }
    sort(all+1,all+1+T[0]);
    for(int i=1,j;i<=T[0];i=j){
        j=i+1;
        while(j<=T[0]&&all[j].a==all[i].a&&all[j].b==all[i].b) j++;
        ans+=(j-i>=m);
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42403731/article/details/81037408