当前位置 博文首页 > 文章内容

    Codeforces Round #657 (Div. 2) C. Choosing flowers(贪心/前缀和/二分/枚举)

    作者: 栏目:未分类 时间:2020-07-20 16:00:17

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    Vladimir would like to prepare a present for his wife: they have an anniversary! He decided to buy her exactly nn flowers.

    Vladimir went to a flower shop, and he was amazed to see that there are mm types of flowers being sold there, and there is unlimited supply of flowers of each type. Vladimir wants to choose flowers to maximize the happiness of his wife. He knows that after receiving the first flower of the ii -th type happiness of his wife increases by aiai and after receiving each consecutive flower of this type her happiness increases by bibi . That is, if among the chosen flowers there are xi>0xi>0 flowers of type ii , his wife gets ai+(xi−1)⋅biai+(xi−1)⋅bi additional happiness (and if there are no flowers of type ii , she gets nothing for this particular type).

    Please help Vladimir to choose exactly nn flowers to maximize the total happiness of his wife.

    Input

    The first line contains the only integer tt (1≤t≤100001≤t≤10000 ), the number of test cases. It is followed by tt descriptions of the test cases.

    Each test case description starts with two integers nn and mm (1≤n≤1091≤n≤109 , 1≤m≤1000001≤m≤100000 ), the number of flowers Vladimir needs to choose and the number of types of available flowers.

    The following mm lines describe the types of flowers: each line contains integers aiai and bibi (0≤ai,bi≤1090≤ai,bi≤109 ) for ii -th available type of flowers.

    The test cases are separated by a blank line. It is guaranteed that the sum of values mm among all test cases does not exceed 100000100000 .

    Output

    For each test case output a single integer: the maximum total happiness of Vladimir's wife after choosing exactly nn flowers optimally.

    Example

    Input

    Copy

    2

    4 3

    5 0

    1 4

    2 2

     

    5 3

    5 2

    4 2

    3 1

    Output

    Copy

    14

    16

    我好菜我好菜我好菜….一开始以为是简单的不断查询区间最值+单点修改就写了线段树,结果发现我是傻逼。二分又调了半天…

    仔细一想思路还是很简单的,注意到:只有一种花会被取两次及以上。因为如果有两种以上的花被取多次,不如全换成这些花内b值最高的那一种。

    因此我们先把ai和bi捆绑成结构体,按照a从大到小排序,然后依次枚举每个ai-bi组(设这一种花会被取两次以上,其他花都最多被取一次)。然后在数组中二分查找小于等于bi的ai的位置pos,再把这个位置-1。这样1~pos全都是大于bi的a的值,前缀和可以O(1)求出,再加上(n – pos) * bi 就是答案了。但这样还有点问题。一是pos大于n了,这样按上面算的话会使答案偏大,此时只需要求前n个ai的前缀和并把它作为答案即可。二是如果当前枚举到的位置大于pos,此时即使ai很小也必须浪费一个位置来买(这样才能买到开心值很大的bi的花),因此答案就是买前pos朵开心值为a1~apos的花,加上一朵开心值为ai的花以及n – pos – 1朵开心值为bi的花。

    #include <bits/stdc++.h>
    #define N 100005
    using namespace std;
    struct point
    {
        long long a;
        long long b;
    }p[N];
    long long sum[N] = {0}, mysort[N], n, m;
    bool cmp(point x, point y)//按a排序 
    {
        if(x.a != y.a) return x.a > y.a;
        else return x.b > y.b;
    }
    int main()
    {
        int t;
        cin >> t;
        sum[0] = 0;
        while(t--)
        {
            cin >> n >> m;
            long long ans = 0;
            long long mmax = 0;
            for(int i = 1; i <= m; i++)
            {
                scanf("%d%d", &p[i].a, &p[i].b);
                mmax = max(mmax, p[i].a);
            }
            sort(p + 1, p + m + 1, cmp);
            for(int i = 1; i <= m; i++) 
            {
                sum[i] = sum[i - 1] + p[i].a;
                mysort[i] = p[i].a;
            }
            for(int i = 1; i <= m; i++)
            {
                int pos = lower_bound(mysort + 1, mysort + m + 1, p[i].b, greater<int>()) - mysort;//找到第一个小于等于p[i].b的位置 -1的话就得到大于p[i].b的位置
                pos--;
                if(pos > n) ans = max(ans, sum[n]);//别忘了n比较小的情况!! 
                else if(pos < i) ans = max(ans, 1ll * sum[pos] + p[i].a + 1ll * (n - pos - 1) * p[i].b);
                else ans = max(ans, 1ll * sum[pos] + 1ll * (n - pos) * p[i].b);
            }
            cout << ans << endl;
        }
    }