Handshake(二分答案)

Handshake(二分答案)

题目描述
Takahashi has come to a party as a special guest. There are N ordinary guests at the party. The i
-th ordinary guest has a power of Ai.
Takahashi has decided to perform M handshakes to increase the happiness of the party (let the current happiness be 0). A handshake will be performed as follows:
·Takahashi chooses one (ordinary) guest x for his left hand and another guest y for his right hand (x and y can be the same).
·Then, he shakes the left hand of Guest x and the right hand of Guest y simultaneously to increase the happiness by Ax+Ay.
However, Takahashi should not perform the same handshake more than once. Formally, the following condition must hold:
·Assume that, in the k-th handshake, Takahashi shakes the left hand of Guest xk and the right hand of Guest yk. Then, there is no pair p,q (1≤p<q≤M) such that (xp,yp)=(xq,yq).
What is the maximum possible happiness after M handshakes?

Constraints
·1≤N≤105
·1≤M≤N2
·1≤Ai≤105
·All values in input are integers.

输入
Input is given from Standard Input in the following format:

N M
A1 A2 … AN

输出
Print the maximum possible happiness after M handshakes.
样例输入 Copy
【样例1】
5 3
10 14 19 34 33
【样例2】
9 14
1 3 5 110 24 21 34 5 3
【样例3】
9 73
67597 52981 5828 66249 75177 64141 40773 79105 16076
样例输出 Copy
【样例1】
202
【样例2】
1837
【样例3】
8128170
提示
样例1解释
Let us say that Takahashi performs the following handshakes:
·In the first handshake, Takahashi shakes the left hand of Guest 4 and the right hand of Guest 4.
·In the second handshake, Takahashi shakes the left hand of Guest 4 and the right hand of Guest 5.
·In the third handshake, Takahashi shakes the left hand of Guest 5 and the right hand of Guest 4.
Then, we will have the happiness of (34+34)+(34+33)+(33+34)=202.
We cannot achieve the happiness of 203 or greater, so the answer is 202.
题意:大概是从n个元素构造一个n*n的矩阵,求最大的m个元素。
思路:二分求到最小的符合条件的值。ans=ans-(cnt-m)*mid;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
 
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
#define ms(s) memset(s, 0, sizeof(s))
 
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll , ll> pi;
typedef unordered_map<int,int> un_map;
template<class T>
inline void read (T &x) {
    x = 0;
    int sign = 1;
    char c = getchar ();
    while (c < '0' || c > '9') {
        if ( c == '-' ) sign = - 1;
        c = getchar ();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar ();
    }
    x = x * sign;
}
 
const int maxn = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const ll INF = ll(1e18);
const int mod = 1e9+7;
const double PI = acos(-1);
#define LOCAL
 
 
int n;
ll m,a[maxn];
ll sum[maxn];
ll ans = 0,cnt= 0,pos=0;
bool check(ll mid) {
     rep(i,1,n){
        ll p = lower_bound(a+1,a+1+n,mid-a[i])-a;
        cnt+=n-p+1;
        ans+=sum[n]-sum[p-1]+a[i]*(n-p+1);
     }
     if(cnt>=m) return true;
     return false;
}
void solve() {
    rep(i,1,n) read(a[i]);
    sort(a+1,a+1+n);
    rep(i,1,n) sum[i]=sum[i-1]+a[i];
    ll l = a[1]+a[1],r= a[n]+a[n];
    while(l<=r) {
        ll mid=(l+r)>>1;
        ans = 0,cnt= 0;
        if(check(mid)) {
            pos=mid;
            l=mid+1;
        }
        else r=mid-1;
    }
    printf("%lld\n", ans-(cnt-m)*pos);
 
}
int main(int argc, char * argv[])
{
    //freopen("/home/yesky/桌面/date.in", "r", stdin);
    //freopen("/home/yesky/桌面/date.out", "w", stdout);
    while(~scanf("%d%lld",&n,&m)) {
        solve();
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值