传送门
一道简单的字符串。这里收集了几种经典做法:
- SAM,不想写。
- 后缀数组+二分,不想写
- 后缀数组+单调队列,不想写
- hash+二分,for循哈希,天下无敌!于是妥妥的hash
代码如下:
#include<bits/stdc++.h>
#define N 20005
#define Base 20001
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
return ans;
}
inline void write(int x){
if(x>9)write(x/10);
putchar(x%10+'0');
}
int n,a[N],b[N],k;
map<unsigned int,int>mp;
unsigned int sum[N],bas[N];
int main(){
n=read(),k=read();
bas[0]=1;
for(int i=1;i<=n;++i)a[i]=b[i]=read(),bas[i]=bas[i-1]*Base;
sort(b+1,b+n+1);
int siz=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;++i){
a[i]=lower_bound(b+1,b+siz+1,a[i])-b;
sum[i]=sum[i-1]*Base+a[i];
}
int l=0,r=n;
while(l<=r){
mp.clear();
int mid=l+r>>1,cnt=0;
for(int i=1;i+mid<=n;++i)cnt=max(cnt,++mp[sum[i+mid]-sum[i-1]*bas[mid+1]]);
if(cnt>=k)l=mid+1;
else r=mid-1;
}
printf("%d",l);
return 0;
}