基准时间限制:1 秒 空间限制:131072 KB 分值: 40
难度:4级算法题
Input
第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31
Output
一个数表示答案。
Input示例
4 2 1 2 3 2
Output示例
2
二分答案验证即可.... 这种也算是一种题型,
验证的时候用滑动窗口来实现即可,数据量大,开数组会爆内存,那么就离散化
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100000+10;
int a[N],b[N],num[N];
int n;
ll k;
bool check(int x)
{
memset(num,0,sizeof(num));
int l=0,r=0,flag=-1;
ll ans=0;
while(r<=n) {
if(flag==-1) {
if(r==n) break;
num[a[r]]++;
if(num[a[r]]>=x) flag=x;
r++;
}
else {
while(flag!=-1) {
ans=ans+n-r+1;
num[a[l]]--;
l++;
if(num[a[r-1]]<x) flag=-1;
}
}
}
if(ans>=k) return true;
return false;
}
int main()
{
int i,j,cnt;
scanf("%d%I64d",&n,&k);
for(i=0;i<n;i++) {
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b,b+n);
cnt=unique(b,b+n)-b;
for(i=0;i<n;i++) {
a[i]=lower_bound(b,b+cnt,a[i])-b;
}
int l=1,r=n,mid;
while(l<=r) {
mid=(l+r)>>1;
if(check(mid)) l=mid+1;
else r=mid-1;
}
printf("%d\n",r);
return 0;
}