Comet OJ - Contest #3 (A 比賽 增強版)二分答案

考試的時候同屆神犇 JZYshurak 出了一個  n=$10^5$ 的數據增強版. c++

剛開始沒什麼思路,可是突然想到這個能夠轉成二分斷定+暴力枚舉的模型. spa

二分 ans, 使得大於等於 ans 的值小於 k 個,這樣就能保證只需枚舉小於 k 個值了. code

code: blog

#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; 
}
相關文章
相關標籤/搜索