codeforces 721D. Maxim and Array(贪心)

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Recently Maxim has found an array of n integers, needed by no one. He immediately come up with idea of changing it: he invented positive integer x and decided to add or subtract it from arbitrary array elements. Formally, by applying single operation Maxim chooses integer i (1 ≤ i ≤ n) and replaces the i-th element of array ai either with ai + x or with ai - x. Please note that the operation may be applied more than once to the same position.

Maxim is a curious minimalis, thus he wants to know what is the minimum value that the product of all array elements (i.e. ) can reach, if Maxim would apply no more than k operations to it. Please help him in that.


Input

The first line of the input contains three integers n, k and x (1 ≤ n, k ≤ 200 000, 1 ≤ x ≤ 109) — the number of elements in the array, the maximum number of operations and the number invented by Maxim, respectively.

The second line contains n integers a1, a2, ..., an () — the elements of the array found by Maxim.


Output

Print n integers b1, b2, ..., bn in the only line — the array elements after applying no more than k operations to the array. In particular,  should stay true for every 1 ≤ i ≤ n, but the product of all array elements should be minimum 

possible.

If there are multiple answers, print any of them.

Examples
input
5 3 1
5 4 3 5 2
output
5 4 3 5 -1 
input
5 3 1
5 4 3 5 5
output
5 4 0 5 5 
input
5 3 1
5 4 4 5 5
output
5 1 4 5 5 
input
3 2 7
5 4 2
output
5 11 -5 

题意:

有n个数,k次操作,每次操作可以将第i个数+x或者-x,输出k次操作后这n个数乘积最小时的数列

题意:

先将这个数列从小到大 排序,如果这个数列中有偶数个负数,那么就尽可能的处理出奇数个负数

然后每次取出绝对值最小的数,负数就-x,正数就+x

这样处理出来的就是乘积最小的

#include <bits/stdc++.h>
using namespace std;
#define ll __int64
const int N=2e5+10;

struct node{
	ll a, aa;
	int id;
	friend bool operator < (const node n1, const node n2){
		return n1.aa > n2.aa;
	}
}arr[N];

priority_queue<node>q;

bool cmp1(node n1, node n2){
	if(n1.a!=n2.a) return n1.a<n2.a;
	return n1.id<n2.id;
}
ll ans[N];

int main(){
	int n, k;
	ll x;
	scanf("%d%d%I64d", &n, &k, &x);
	for(int i=0; i<n; i++) scanf("%I64d", &arr[i].a), arr[i].id=i;
	sort(arr, arr+n, cmp1);
	int kk=0;
	for(kk=0; kk<n; kk++){
		if(arr[kk].a>=0) break;
	}
	//有偶数个负数,尽可能的处理出奇数个负数 
	if(kk%2==0){
		if(kk==0) {
			while(k--) {
				arr[0].a-=x;
				if(arr[0].a<0) break;
			}
		}
		else if(kk==n){
			while(k--) {
				arr[n-1].a+=x;
				if(arr[n-1].a>=0) break;
			}
		}
		else{
			arr[kk-1].aa = abs(arr[kk-1].a);
			arr[kk].aa = arr[kk].a;
			if(arr[kk-1].aa<arr[kk].aa){
				while(k--) {
					arr[kk-1].a+=x;
					if(arr[kk-1].a>=0) break;
				}
			}
			else{
				while(k--) {
					arr[kk].a-=x;
					if(arr[kk].a<0) break;
				}
			}
		}
	}
	while(!q.empty()) q.pop();
	for(int i=0; i<n; i++){
		arr[i].aa = abs(arr[i].a);
		q.push(arr[i]);
	}
	if(k>=0){
		while(k--){
			node s = q.top();q.pop();
			s.aa+=x;
			if(s.a<0) s.a = -s.aa;
			else s.a = s.aa;
			q.push(s);
		}
	}
	
	while(!q.empty()) {
		node s = q.top();q.pop();
		ans[s.id] = s.a;
	}
	for(int i=0; i<n; i++){
		if(i==n-1) printf("%I64d\n", ans[i]);
		else printf("%I64d ", ans[i]);
	}
	return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值