题意
求至少重复出现k次的字串的最大长度
思路
对于最大长度s的字串,当i>s时肯定不符合但是对于i<s时都是符合的,所以可以用二分查找长度然后用hash匹配,总复杂度lgn*nlgn,少用map!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=22222;
typedef unsigned long long ull;
ull xp[MAXN],hash_1[MAXN];
const int seed=13337;
int num[MAXN];
void init()
{
xp[0]=1;
for(int i=1;i<MAXN;i++)
xp[i]=xp[i-1]*seed;
}
int n,k;
void make_hash()
{
hash_1[n]=0;
for(int i=n-1;i>=0;i--)
hash_1[i]=hash_1[i+1]*seed+num[i];
}
ull get_hash(int i,int L)
{
return hash_1[i]-hash_1[i+L]*xp[L];
}
ull ans[MAXN];
bool check(int L)
{
int cont=0;
for(int i=0;i<n-L+1;i++)
{
ans[cont++]=get_hash(i,L);
}
sort(ans,ans+cont);
for(int i=0;i<cont;i++)
{
int k1=0;
int j;
for(j=i;j<cont;j++)
{
if(ans[i]==ans[j])
k1++;
else break;
}
i=j-1;
if(k1>=k) return true;
}
return false;
}
int main()
{
cin>>n>>k;
init();
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
make_hash();
int l=0;
int r=n;
int mid;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)) l=mid+1;
else r=mid-1;
}
printf("%d\n",(l+r)>>1);
return 0;
}