Codeforces 1283 D. Christmas Trees

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>
typedef long long ll;
const ll mod = 9999999967;
using namespace std;
namespace fastIO {
    inline void input(int& res) {
        char c = getchar();res = 0;int f = 1;
        while (!isdigit(c)) { f ^= c == '-'; c = getchar(); }
        while (isdigit(c)) { res = (res << 3) + (res << 1) + (c ^ 48);c = getchar(); }
        res = f ? res : -res;
    }
    inline ll qpow(ll a, ll b) {
        ll ans = 1, base = a;
        while (b) {
            if (b & 1) ans = (ans * base % mod +mod )%mod;
            base = (base * base % mod + mod)%mod;
            b >>= 1;
        }
        return ans;
    }
}
using namespace fastIO;
const int N = 2e5 + 5;
struct node{
	int pos;
};
int Case,n,m,x,cnt,ss;
ll ans;
queue<node> q;
map<int,int> mp,dis,vis,tt;
int main(){
	Case=1;
	//input(Case);
	while(Case--){
		input(n),input(m);
		for(int i=1;i<=n;i++){
			input(x);
			q.push({x});
			mp[x]=1;
			dis[x]=1;
			vis[x]=1;
		}
		while(cnt<m){
			node t = q.front();
			q.pop();
			if(!mp[t.pos+1]){
				ans+=dis[t.pos];
				dis[t.pos+1]=dis[t.pos]+1;
				mp[t.pos+1]=1;
				q.push({t.pos+1});
				cnt++;
			}
			if(cnt == m) break;
			else if(!mp[t.pos-1]){
				ans+=dis[t.pos];
				dis[t.pos-1]=dis[t.pos]+1;
				mp[t.pos-1]=1;
				q.push({t.pos-1});
				cnt++;
			}
		}
		printf("%lld\n",ans);
		for (auto i:mp)
			if(!vis[i.first]) printf("%d ",i);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值