Codeforces Round #611 (Div. 3) D. Christmas Trees(贪心+思维)

题目链接:https://codeforc.es/contest/1283/problem/D

There are n Christmas trees on an infinite number line. The i-th tree grows at the position xi. All xi are guaranteed to be distinct.

Each integer point can be either occupied by the Christmas tree, by the human or not occupied at all. Non-integer points cannot be occupied by anything.

There are m people who want to celebrate Christmas. Let y1,y2,…,ym be the positions of people (note that all values x1,x2,…,xn,y1,y2,…,ym should be distinct and all yj should be integer). You want to find such an arrangement of people that the value ∑j=1mmini=1n|xi−yj| is the minimum possible (in other words, the sum of distances to the nearest Christmas tree for all people should be minimized).

In other words, let dj be the distance from the j-th human to the nearest Christmas tree (dj=mini=1n|yj−xi|). Then you need to choose such positions y1,y2,…,ym that ∑j=1mdj is the minimum possible.

Input
The first line of the input contains two integers n and m (1≤n,m≤2⋅105) — the number of Christmas trees and the number of people.

The second line of the input contains n integers x1,x2,…,xn (−109≤xi≤109), where xi is the position of the i-th Christmas tree. It is guaranteed that all xi are distinct.

Output
In the first line print one integer res — the minimum possible value of ∑j=1mmini=1n|xi−yj| (in other words, the sum of distances to the nearest Christmas tree for all people).

In the second line print m integers y1,y2,…,ym (−2⋅109≤yj≤2⋅109), where yj is the position of the j-th human. All yj should be distinct and all values x1,x2,…,xn,y1,y2,…,ym should be distinct.

If there are multiple answers, print any of them.

Examples

input

2 6
1 5

output

8
-1 2 6 4 0 3 

input

3 5
0 3 1

output

7
5 -2 4 -1 2 

题意

有 n 个树和 m 个人,给出每棵树的位置,求所有人与最近的树的距离的和的最小值,以及这个情况所有人的位置。

分析

我们可以先从每棵树距离为 1 的点去取位置,如果不够,那么再从离每棵树距离为 2 的点取位置…
这个方法如果依次遍历每棵树的话复杂度过大,有些树不用进行判断,还有的树在使用过几次之后也不用进行判断。
根据贪心思想,肯定不可能跨树取位置,所以每棵树取的最大位置就是距离它前后两棵树距离的最大值。那么我们可以先处理出没棵树的最大距离(注意第一棵树和最后一棵树的最大距离是无限的),然后再遍历和每棵树的距离,再遍历在这个距离下符合要求的树,位置够了以后就退出循环。

代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int n,m;
ll tr[200007];
struct node{
	ll pos;
	ll sz;
};
queue<node> TT;
queue<int> q;
map<ll,ll> vis;

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&tr[i]), vis[tr[i]] = 1;
	sort(tr + 1, tr + 1 + n);
	int j = 1;
	ll k;
	k = 0;
	
	while(j <=n)
	{
		if(j == 1 || j == n) TT.push({tr[j], 0});
		if(j == n) break;
		ll length = max(tr[j] - tr[j - 1] - 1, tr[j + 1] - tr[j] - 1);
		if(length > 0) TT.push({tr[j], length});
		j++;
	}
	
	int sum = 0;
	int len = 1;
	ll ans = 0;
	while(sum < m)
	{
		int times = TT.size();
		for(int i=0;i<times;i++)
		{
			node now = TT.front();
			TT.pop();
			ll pos = now.pos;
			if(vis[pos + len] == 0)
			{
				vis[pos + len] = 1;
				if(sum < m)
				{
					ans += len;
					q.push(pos + len);
				}
				sum++;
			}
			if(vis[pos - len] == 0)
			{
				vis[pos - len] = 1;
				if(sum < m)
				{
					ans += len;
					q.push(pos - len);
				}
				sum++;
			}
			if(now.sz == 0 || len < now.sz) TT.push(now);
		}
		len++;
	}
	printf("%lld\n",ans);
	while(!q.empty())
	{
		printf("%d ",q.front());
		q.pop();
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值