[51nod1686]第k大区间
题目传送门这个是满足二分性的,只需要二分判断一下是否成立就可以了。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;long long a[100005],b[100005];long long calc(...
·
题目传送门
这个是满足二分性的,只需要二分判断一下是否成立就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a[100005],b[100005];
long long calc(long long x)
{
return x>0 ? x*(x-1)/2 : 0;
}
long long n,k;
long long check(long long x)
{
long long tot=0;
long long l=0,r,last=0;
memset(b,0,sizeof(b));
for(r=1;r<=n;r++)
{
b[a[r]]++;
if(b[a[r]]>x)
{
tot+=calc(r-l-1);
tot-=calc(last-l-1);
while(b[a[r]]>x)
{
l++;
b[a[l]]--;
}
last=r;
}
}
tot+=calc(r-l-1);
tot-=calc(last-l-1);
return tot;
}
long long ans;
void erfen(long long l,long long r)
{
ans=r;
if(l==r)
{
ans=r;
return;
}
long long mid=l+r>>1;
if(check(mid)<k)
{
erfen(mid+1,r);
}
else
{
erfen(l,mid);
}
}
int main()
{
scanf("%lld%lld",&n,&k);
for(long long i=1;i<=n;i++)
scanf("%lld",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
long long tot=(int)(unique(b+1,b+n+1)-(b+1));
for(long long i=1;i<=n;i++)
{
a[i]=(int)(lower_bound(b+1,b+tot+1,a[i])-b);
}
k=calc(n)-k+1;
erfen(0,n);
cout<<ans<<'\n';
return 0;
}
更多推荐
已为社区贡献2条内容
所有评论(0)