题目大意:
寻找出现次数为k的最长的子串。
解决方法:
字符串hash
我的代码:
#include <cstdio>
#include <string>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#define maxn 20010
#define ull unsigned long long
#define seed 131
using namespace std;
ull base[maxn],bs[maxn];
int a[maxn],n,k;
int yes(int len){
int ub=0;
for (int i=0;i<len;i++) ub=ub*seed+a[i];
bs[0]=ub;
for (int i=0;i+len<=n;i++) {
ub=ub*seed+a[i+len]-a[i]*base[len];
bs[i+1]=ub;
}
sort(bs,bs+n-len+1);int num=0;
for (int i=0;i<n-len+1;i++){
if (i&&bs[i]!=bs[i-1]) num=1;
else num++;
if (num>=k) return 1;
//if (len==4) cout <<"III"<<k<<" "<<bs[i]<<endl;
}
return 0;
}
int main (){
//freopen("test.in","r",stdin);
base[0]=1;
for (int i=1;i<maxn;i++) base[i]=base[i-1]*seed;
while (~scanf("%d%d",&n,&k)){
for (int i=0;i<n;i++) scanf("%d",&a[i]);
int l,r;l=1;r=n;
while (l<r){
int m=(r+l)/2;
//cout<<l<<" "<<r<<" "<<yes(4)<<endl;
if (yes(m)) l=m;
else r=m-1;
if (l==r-1){
if (yes(r)) l=r;
else r=l;
}
}
printf("%d\n",l);
}
return 0;
}