AtCoder Beginner Contest 149 E.Handshake
Problem Statement
(略)
题目来源
Sample Input 1
5 3
10 14 19 34 33
Sample Output 1
202
Sample Output 2
1837
Sample Input 3
9 73
67597 52981 5828 66249 75177 64141 40773 79105 16076
Sample Output 3
8128170
比赛时根本想不到用二分,太菜了/(ㄒoㄒ)/~~,因为任意两数之和最大2e5,所以可以二分找到符合条件的最小和,最后再算一遍输出即可:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+5;
ll sum[N],a[N],m,n;
int main()
{
cin>>n>>m;
for(ll i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
for(ll i=1;i<=n;i++){
sum[i]=sum[i-1]+a[i];
}
ll l=0,r=2e5+1,ans,res,cnt;
while(l<=r){
ll mid=(l+r)>>1;
res=cnt=0;
for(ll i=1;i<=n;i++){
ll pos=lower_bound(a+1,a+n+1,mid-a[i])-a;
cnt+=n-pos+1;
res+=sum[n]-sum[pos-1]+a[i]*(n-pos+1);
}
if(cnt>=m){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%lld\n",res-(cnt-m)*ans);
}