Codeforces Round #523 (Div. 2) B,D

B

You came to the exhibition and one exhibit has drawn your attention. It consists of n stacks of blocks, where the i-th stack consists of ai

blocks resting on the surface.

The height of the exhibit is equal to m

. Consequently, the number of blocks in each stack is less than or equal to m

.

There is a camera on the ceiling that sees the top view of the blocks and a camera on the right wall that sees the side view of the blocks.

Find the maximum number of blocks you can remove such that the views for both the cameras would not change.

Note, that while originally all blocks are stacked on the floor, it is not required for them to stay connected to the floor after some blocks are removed. There is no gravity in the whole exhibition, so no block would fall down, even if the block underneath is removed. It is not allowed to move blocks by hand either.

Input

The first line contains two integers n

and m (1≤n≤100000, 1≤m≤109

) — the number of stacks and the height of the exhibit.

The second line contains n

integers a1,a2,…,an (1≤ai≤m

) — the number of blocks in each stack from left to right.

Output

Print exactly one integer — the maximum number of blocks that can be removed.

思路 : 我们把每一列从小到大排序;然后贪心,每一排最少可以移除到只剩一个,遇到某一排在当前情况下需要保留多个的情况,也就是说如果后面存在相邻两排高度相等时,是可以移除的,我们把后面有可能移除的个数res记录下来,遇到两排相登时,--直到res为0;

#include<bits/stdc++.h>

using namespace std;

int a[100005];

int main()
{
    int n, m;
    cin >> n >> m;
    long long mx =0;
    for(int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a, a+n);
//    for(int i = 0; i < n; i++)
    //    cout << a[i] << " ";
    cout << endl;
    int s = 0, num = a[0]-1;
    for(int  i = 1; i < n; i++)
    {
        if(a[i] == a[i-1])
        {
            if(num)
            {
                mx += a[i];
                num--;
            }
            else
                mx += (a[i]-1);
        }
        else
        {
            mx += a[i-1];
            num += (a[i]-a[i-1]-1);
        }
    //    cout << mx << endl;
    }
    cout << mx << endl;
}
/*

5 8
2 4 4 5 5

*/

D

There are n TV shows you want to watch. Suppose the whole time is split into equal parts called "minutes". The i-th of the shows is going from li-th to ri

-th minute, both ends inclusive.

You need a TV to watch a TV show and you can't watch two TV shows which air at the same time on the same TV, so it is possible you will need multiple TVs in some minutes. For example, if segments [li,ri]

and [lj,rj] intersect, then shows i and j

can't be watched simultaneously on one TV.

Once you start watching a show on some TV it is not possible to "move" it to another TV (since it would be too distracting), or to watch another show on the same TV until this show ends.

There is a TV Rental shop near you. It rents a TV for x

rupees, and charges y (y<x) rupees for every extra minute you keep the TV. So in order to rent a TV for minutes [a;b] you will need to pay x+y⋅(b−a)

.

You can assume, that taking and returning of the TV doesn't take any time and doesn't distract from watching other TV shows. Find the minimum possible cost to view all shows. Since this value could be too large, print it modulo 109+7

.

Input

The first line contains integers n

, x and y (1≤n≤105, 1≤y<x≤109

) — the number of TV shows, the cost to rent a TV for the first minute and the cost to rent a TV for every subsequent minute.

Each of the next n

lines contains two integers li and ri (1≤li≤ri≤109) denoting the start and the end minute of the i

-th TV show.

Output

Print exactly one integer — the minimum cost to view all the shows taken modulo 109+7

.

Examples

Input

Copy

5 4 3
1 2
4 10
2 4
10 11
5 9

Output

Copy

60

Input

Copy

6 3 2
8 20
6 22
4 15
20 28
17 25
20 27

Output

Copy

142

Input

Copy

2 1000000000 2
1 2
2 3

Output

Copy

999999997

思路:

看数据就知道只能O(nlogn),O(n)做;考虑O(n)的做法。花费 = x*电视数目+y*节目时长+y*中间空闲时长;

节目时长很简单,只需要考虑数目和空闲时间,对于每一段空闲时长*y一定是小于x的;具体看代码。

#include<bits/stdc++.h>

using namespace std;
#define ll long long
const int mod = 1e9 + 7;
int s[100005], e[100005];
priority_queue<int> hay;
int main()
{
    int n , x, y;
    while(cin >> n >> x >> y)
    {
        int ss =0, ee=0;
        ll ans = 0;
        for(int i = 0; i < n; i++)
        {
            cin >> s[i] >> e[i];
            ans += (ll)(e[i]-s[i])*y%mod;
            ans %= mod;
        }
    //    cout << ans << endl;
        sort(s, s+n);
        sort(e, e+n);
        while(ss < n && ee < n)
        {
            if(s[ss] > e[ee])
            {
                hay.push(e[ee++]);
            }
            else
            {
                int tmp = s[ss];
                if(!hay.empty() && (ll)(tmp-hay.top())*y >= x)
                {
                    while (!hay.empty()) hay.pop();
                }
                if(hay.empty())
                {
                    ans += x;
                    ans %= mod;
                }
                else
                {
                    ans += (ll)(tmp-hay.top())*y;
                    ans %= mod;
                    hay.pop();
                }
            //    cout << ans << endl;
                ss++;
            }
        }
        cout << ans << endl;
    }
}
因为我喜欢追寻过程中的自己
原文地址:https://www.cnblogs.com/IzuruKamuku/p/14359798.html