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; }