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。
输出一行一个整数,表示文章的评分
输出一行一个整数,表示文章的评分
代码: 比较好看懂。
#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); }