Jzoj5462【NOIP2017提高A組衝刺11.8】好文章
阿新 • • 發佈:2019-01-23
nodgd寫了一篇文章,自認為這是一篇好文章。nodgd的文章由n個小寫英文字母組成。文章的一個子串指的是文章中的一段連續的字母,子串的長度就是這一段的字母個數。nodgd在文章中用了排比、對偶、前後照應之類的手法,所以就有很多個子串是相同或者相近的。為了向大家證明這是一篇好文章,nodgd決定給自己的文章進行評分。nodgd首先確定了一個整數m,然後統計出文章中有多少個不相同的長度為m的子串,這個數量就是文章的評分。
然而,nodgd懶得老老實實計算這個評分了,就把任務丟給了你。
這個題卡雜湊,要麼用雙雜湊,還是sam比較穩'233333',雜湊就是拿來對拍的
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 400010
using namespace std;
char str[N];
int s[N][26],mx[N],sz[N],f[N];
int cnt=1,lst=1,r[N],v[N],n,m,ans=0;
int extend(char c){
int p=lst,np=lst=++cnt,q,nq;
c-='a'; mx[np]=mx[p]+1;
for(;p&&!s[p][c];p=f[p]) s[p][c]=np;
if(!p) return f[np]=1;
q=s[p][c];
if(mx[q]==mx[p]+1) f[np]=q;
else {
nq=++cnt;
mx[nq]=mx[p]+1;
f[nq]=f[q]; f[q]=f[np]=nq;
memcpy(s[nq],s[q],26<<2);
for(;p&&s[p][c]==q;p=f[p]) s[p][c]=nq;
}
}
int main(){
freopen("article.in","r",stdin);
freopen("article.out","w",stdout);
scanf("%d%d%s" ,&n,&m,str+1);
for(int i=1;i<=n;++i) extend(str[i]);
for(int i=1;i<=cnt;++i) ++v[mx[i]];
for(int i=1;i<=n;++i) v[i]+=v[i-1];
for(int i=cnt;i;--i) r[v[mx[i]]--]=i;
for(int p,i=cnt;i;--i){
p=r[i];
if(mx[p]>=m && mx[f[p]]<m) ans++;
}
printf("%d\n",ans);
}