基准时间限制: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
相关问题
- -这个题是二分答案问题 ,二分答案,然后看有多少个比这个答案大的区间。
然后继续二分。
每次二分 有一次 o(n) 的遍历,遍历使用尺取法。
这里有一个细节 。
就是贡献度 。
这里的贡献度 ,是上一次贡献的地方截至 到下一个结束的地方,,这个范围是都有贡献度的。
#include <bits/stdc++.h>
using namespace std;
int a[1000005],b[100005];
int num[100005];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b,b+n);
for(int i=0;i<n;i++)
{
a[i]=lower_bound(b,b+n,a[i])-b;
}
int le=1,re=n,mid;
while(le<=re)
{
mid=(le+re)/2;
long long sum=0,s=0,l=0,r=0,z=0;
memset(num,0,sizeof(num));
while(l<=r&&r<=n)
{
if(z)
{
int se=0;
while(num[a[r-1]]>=mid)
{
num[a[l]]--;
se++;
l++;
}
z=0;
sum+=se*(n-r+1);
}
if(z==0)
{
num[a[r]]++;
if(num[a[r]]==mid) z=1;
r++;
}
}
if(sum>=k) le=mid+1;
else if(sum<k) re=mid-1;
}
cout<<re<<endl;
}
}