Comet OJ - Contest #3 (A 比赛 加强版)二分答案
考试的时候同届神犇 JZYshurak 出了一个 n=$10^5$ 的数据加强版.
刚开始没什么思路,但是忽然想到这个可以转成二分判定+暴力枚举的模型.
二分 ans, 使得大于等于 ans 的值小于 k 个,这样就能保证只需枚举小于 k 个值了.
code:
#include <bits/stdc++.h>
#define ll long long
#define N 300002
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
int n,k;
ll A[N];
int check(ll tmp)
{
int i,j;
ll re=0;
for(i=n;i>=1;--i)
{
j=lower_bound(A+1,A+1+n,tmp-A[i])-A;
if(j<i)
{
re+=i-j;
}
}
return re<1ll*k;
}
int main()
{
int i,j;
setIO("onevsk");
scanf("%d%d",&n,&k);
for(i=1;i<=n;++i) scanf("%lld",&A[i]);
sort(A+1,A+1+n);
ll l=1, r=2000000001, mid,ans=0;
while(l<=r)
{
// 大于 mid 有 k 个
mid=(l+r)>>1;
if(check(mid)) ans=mid, r=mid-1;
else l=mid+1;
}
ll re=0;
int pp=0;
for(i=n;i>=1;--i)
{
for(j=i-1;j>=1;--j)
{
if(A[i]+A[j]<ans) break;
re+=A[i]+A[j];
++pp;
}
}
re+=1ll*(1ll*k-1ll*pp)*(ans-1);
printf("%lld\n",re);
return 0;
}

浙公网安备 33010602011771号