题意:中文
思路:我们可以二分要求的那个次数,然后对于每次判断遍历整个数组求出大于等于mid的个数即可,用vector寸一下个数即可
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=100010;
vector<int>G[maxn];
int a[maxn],b[maxn],tmp[maxn],n,fn;
ll k;
bool judge(int mid){
for(int i=1;i<=n;i++) G[i].clear();
memset(tmp,0,sizeof(tmp));
ll len=0,ans=0;
for(int i=1;i<=n;i++){
ll t=0;
if(tmp[a[i]]>=mid-1) t=G[a[i]][tmp[a[i]]-mid+1];
len=max(len,t);//代表到i为止的前面从哪开始就有出现大于等于mid的值
ans+=len;
G[a[i]].push_back(i);
tmp[a[i]]++;
}
return ans>=k;
}
int main(){
while(scanf("%d%I64d",&n,&k)!=-1){
for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+1+n);
fn=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+fn,a[i])-b;
int le=1,ri=n,ans=1;
while(le<=ri){
int mid=(le+ri)>>1;
if(judge(mid)) le=mid+1,ans=mid;
else ri=mid-1;
}
printf("%d\n",ans);
}
return 0;
}