CodeForces 580B Kefa and Company

Description:

Kefa wants to celebrate his first big salary by going to restaurant. However, he needs company.

Kefa has n friends, each friend will agree to go to the restaurant if Kefa asks. Each friend is characterized by the amount of money he has and the friendship factor in respect to Kefa. The parrot doesn't want any friend to feel poor compared to somebody else in the company (Kefa doesn't count). A friend feels poor if in the company there is someone who has at least d units of money more than he does. Also, Kefa wants the total friendship factor of the members of the company to be maximum. Help him invite an optimal company!

Input:

The first line of the input contains two space-separated integers, n and d (1 ≤ n ≤ 105) — the number of Kefa's friends and the minimum difference between the amount of money in order to feel poor, respectively.

Next n lines contain the descriptions of Kefa's friends, the (i + 1)-th line contains the description of the i-th friend of type misi (0 ≤ mi, si ≤ 109) — the amount of money and the friendship factor, respectively.

Output:

Print the maximum total friendship factir that can be reached.

Sample Input:

Input:
4 5
75 5
0 100
150 20
75 1
Output:
100
Input:
5 100
0 7
11 32
99 10
46 8
87 54
Output:
111

Hint:

In the first sample test the most profitable strategy is to form a company from only the second friend. At all other variants the total degree of friendship will be worse.

In the second sample test we can take all the friends.

题意:一个人有n个朋友,现在他需要朋友陪同去吃饭,但是陪同的朋友是有条件的(如果有人比其中一人的钱多至少d元,这个人就会不开心),现在他希望陪同的朋友都能开心,并且陪同的朋友友谊值最高。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<queue>
#include<algorithm>
using namespace std;

const int N=1e5+10;
const int INF=0x3f3f3f3f;

struct node
{
    long long num, fee; ///存放钱的数量和友谊值
}no[N];
long long s[N]; ///存放第1个人到第i个人之间的友谊和

int cmp(node s1, node s2)
{
    if (s1.num != s2.num) return s1.num < s2.num;
    return s2.fee < s1.fee;
}

int main ()
{
    long long n, i, j, idex;
    long long ans, sum, d;

    while (scanf("%lld %lld", &n, &d) != EOF)
    {
        for (i = 0; i < n; i++)
            scanf("%lld %lld", &no[i].num, &no[i].fee);

        sort(no, no+n, cmp);

        s[0] = no[0].fee;
        for (i = 1; i < n; i++)
            s[i] = s[i-1] + no[i].fee;

        ans = -INF;

        i = 0; j = n-1;
        while (i < n) ///二分查找每一个符合条件的范围
        {
            long long l, r, m;

            idex = i; ///存放从i开始的最右边的满足条件的下标

            l = i; r = j;

            while (l <= r)
            {
                m = (l+r)/2;

                if (no[m].num-no[i].num < d) ///说明m左边的都满足条件,继续查找右边
                {
                    l = m+1;
                    idex = m;
                }
                else r = m-1;
            }

            sum = s[idex]-s[i]+no[i].fee; ///计算满足条件的友谊和
            ans = max(ans, sum);

            i++;
        }

        printf("%lld
", ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/syhandll/p/4872357.html