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

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;
    }
}

 

上一篇:I.Algorithm Choosing Mushrooms


下一篇:java向mysql中数据时中文乱码