Hash

 

字符数组的输入特殊 char s;scanf(“%s”,s+1) 个别情况要加1;没有&

推荐使用双哈希

  哈希代码:

   

struct set_hash{
    int hash_pow[M];
    int hash_val[M];
    int p,P;
    void _init(int p_,int P_)
    {     p=p_; P=P_;
        hash_pow[0]=1; 
           for(i=1;i<=n;i++)
           {
           hash_val[i]=(1ll*hash_val[i-1]*p+s[i]-'a'+1)%P;
           hash_pow[i]=1ll*hash_pow[i-1]*p%P;
           }
    }
    int _get_hash_val(int l,int r)
    {
        return (hash_val[r]-1ll*hash_val[l-1]*hash_pow[r-l+1]%P+P)%P;
    }
}ha,hb;
int HA[M],HB[M];

不能用sort排序!!!!!!!

有问题,因为是双哈希。

快速排序:

void _qst(int l,int r)
{
    int j,i,m,mm,t;
    i=l,j=r;
    m=HA[(l+r)>>1];
    mm=HB[(l+r)>>1];
    while(i<=j)
    {
        while (HA[i]<m||(HA[i]==m&&HB[i]<mm)) i++;   //关键 
        while (HA[j]>m||(HA[j]==m&&HB[j]>mm)) j--;
        if(i<=j)   // 一点要小于等于,不然无线了 
        {
            t=HA[i];HA[i]=HA[j];HA[j]=t;
            t=HB[i];HB[i]=HB[j];HB[j]=t;
            i++;j--;
        }
    
    }    
    if(i<r) _qst(i,r);
    if(j>l) _qst(l,j);
}

样例

好文章:

nodgd 写了一篇文章,自认为这是一篇好文章。nodgd 的文章由?个小写英
文字母组成。文章的一个子串指的是文章中的一段连续的字母,子串的长度就是
这一段的字母个数。nodgd 在文章中用了排比、对偶、前后照应之类的手法,所
以就有很多个子串是相同或者相近的。为了向大家证明这是一篇好文章,nodgd
决定给自己的文章进行评分。nodgd 首先确定了一个整数?,然后统计出文章中
有多少个不相同的长度为?的子串,这个数量就是文章的评分。
然而,nodgd 懒得老老实实计算这个评分了,就把任务丢给了你。

输入

输入文件 B.in。
第一行包含两个整数?,?,表示文章的长度和需要统计的子串长度。
第二行包含一个长度为?的只包含小写字母的字符串。

输出文件 B.out。
输出一行一个整数,表示文章的评分

样例输入 

5 3
aaaab

样例输出

2

 代码: 比较好看懂。

#include <bits/stdc++.h>
#define M 200010
using namespace std;
char s[M];
int i,n,m;
struct set_hash{
    int hash_pow[M];
    int hash_val[M];
    int p,P;
    void _init(int p_,int P_)
    {     p=p_; P=P_;
        hash_pow[0]=1; 
           for(i=1;i<=n;i++)
           {
           hash_val[i]=(1ll*hash_val[i-1]*p+s[i]-'a'+1)%P;
           hash_pow[i]=1ll*hash_pow[i-1]*p%P;
           }
    }
    int _get_hash_val(int l,int r)
    {
        return (hash_val[r]-1ll*hash_val[l-1]*hash_pow[r-l+1]%P+P)%P;
    }
}ha,hb;
int HA[M],HB[M],t;
void _qst(int l,int r)
{
    int j,i,m,mm,t;
    i=l,j=r;
    m=HA[(l+r)>>1];
    mm=HB[(l+r)>>1];
    while(i<=j)
    {
        while (HA[i]<m||(HA[i]==m&&HB[i]<mm)) i++;   //关键 
        while (HA[j]>m||(HA[j]==m&&HB[j]>mm)) j--;
        if(i<=j)   // 一点要小于等于,不然无线了 
        {
            t=HA[i];HA[i]=HA[j];HA[j]=t;
            t=HB[i];HB[i]=HB[j];HB[j]=t;
            i++;j--;
        }
    
    }    
    if(i<r) _qst(i,r);
    if(j>l) _qst(l,j);
}
int main(){
    scanf("%d%d%s",&n,&m,s+1);
    ha._init(61,1000000007);
    hb._init(97,1000000009);
    for(i=1;i+m-1<=n;i++)
    {
           HA[i]=ha._get_hash_val(i,i+m-1);
           HB[i]=hb._get_hash_val(i,i+m-1);
    }
   _qst(1,n-m+1);
    t=1;
    for(i=2;i<=n-m+1;i++)
    {   
        if(HA[i]!=HA[i-1]||HB[i]!=HB[i-1])
          t++;
    }
    printf("%d",t);
}

 

posted @ 2019-10-09 20:51  VxiaohuanV  阅读(111)  评论(0编辑  收藏  举报