Codeforces F. Maxim and Array(构造贪心)

题目描述:

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 a**i either with a**i + x or with a**i - 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. Codeforces F. Maxim and Array(构造贪心)) 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, ..., a**n (Codeforces F. Maxim and Array(构造贪心)) — the elements of the array found by Maxim.

Output

Print n integers b1, b2, ..., b**n in the only line — the array elements after applying no more than k operations to the array. In particular, Codeforces F. Maxim and Array(构造贪心) 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

Copy

5 3 1
5 4 3 5 2

Output

Copy

5 4 3 5 -1

Input

Copy

5 3 1
5 4 3 5 5

Output

Copy

5 4 0 5 5

Input

Copy

5 3 1
5 4 4 5 5

Output

Copy

5 1 4 5 5

Input

Copy

3 2 7
5 4 2

Output

Copy

5 11 -5

思路:

题目是要求给一个数列,k次操作在某个数上加或减x,让数列乘积最小。因为数有正负,要分情况讨论。

如果现在负数个数是偶数,就是乘积是个正数,应该相办法让它变成负,就让绝对值最小的变,因为它距离零最近。如果要变的是正数,就减x,如果是负数要变,就加x,即使不能让乘积编号也可以让乘积变小。

如果现在负数个数是奇数,乘积是个负数,我们要让乘积的绝对值更大来使乘积更小。就变绝对值最小的,是正数就加x,是负数就减x,因为当一堆数大小越接近,这堆数的乘积越大。

注意每次变化要更新负数的个数,要快速取得绝对值最小的元素,要维护一个结构体的优先级队列,需要在结构体的定义里重载<运算符。

刚开始我沙雕用了两个队列,一个存整数,一个存负数,每次选绝对值小的还要比较,\(if-else\)写了一大堆最后还错了。-_-||详见后面的代码。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#define max_n 200005
using namespace std;
int n,k,x;
long long a[max_n];
struct node
{
int id;
long long val;
bool operator<(const node& a) const
{
return abs(val-0)>abs(a.val-0);
}
};
int cnt = 0;
priority_queue<node> que;
int main()
{
cin >> n >> k >> x;
for(int i = 0;i<n;i++)
{
cin >> a[i];
node nw;
nw.val = a[i];
nw.id = i;
if(a[i]<0)
{
cnt++;
}
que.push(nw);
}
while(k)
{
node nw = que.top();
int id = nw.id;
if(cnt%2==0)
{
if(a[id]<0)
{
a[id] += x;
if(a[id]>=0)
{
cnt--;
}
}
else
{
a[id] -= x;
if(a[id]<0)
{
cnt++;
}
}
}
else
{
if(a[id]<0)
{
a[id] -= x;
}
else
{
a[id] += x;
}
}
nw.val = a[id];
que.pop();
que.push(nw);
k--;
}
for(int i = 0;i<n;i++)
{
cout << a[i] << " ";
}
cout << endl;
}

不明哪里写错的代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#define max_n 200005
using namespace std;
long long n,k,x;
long long a[max_n];
struct node
{
int id;
long long val;
bool operator<(const node& a) const
{
return abs(val-0)>abs(a.val-0);
}
};
priority_queue<node> fque;
priority_queue<node> zque;
int main()
{
cin >> n >> k >> x;
for(int i = 0;i<n;i++)
{
cin >> a[i];
node nw;
nw.val = a[i];
nw.id = i;
if(a[i]<0)
{ fque.push(nw);
}
else
{
zque.push(nw);
}
}
//cout << "input " << endl;
while(k)
{
/*for(int i = 0;i<n;i++)
{
cout << a[i] << " ";
}
cout << endl;*/
if(fque.size()%2==0)
{
if(fque.size()==0)
{
int id = zque.top().id;
a[id] -= x;
node nw;
nw.id = id;
nw.val = a[id];
if(a[id]<0)
{
zque.pop();
fque.push(nw);
}
else
{
zque.pop();
zque.push(nw);
}
}
else if(zque.size()==0)
{
int id = fque.top().id;
a[id] += x;
node nw;
nw.id = id;
nw.val = a[id];
if(a[id]>=0)
{
fque.pop();
zque.push(nw);
}
else
{
fque.pop();
fque.push(nw);
}
}
else
{
int gapz = abs(zque.top().val-0);
int idz = zque.top().id;
int gapf = abs(fque.top().val-0);
int idf = fque.top().id;
if(gapz<gapf)
{
a[idz] -= x;
node nw;
nw.id = idz;
nw.val = a[idz];
if(a[idz]<0)
{
zque.pop();
fque.push(nw);
}
else
{
zque.pop();
zque.push(nw);
}
}
else
{
a[idf] += x;
node nw;
nw.id = idf;
nw.val = a[idf];
if(a[idf]>=0)
{
fque.pop();
zque.push(nw);
}
else
{
fque.pop();
fque.push(nw);
}
}
}
}
else
{
if(zque.size()==0)
{
int id = fque.top().id;
a[id] -= x;
node nw;
nw.id = id;
nw.val = a[id];
fque.pop();
fque.push(nw);
}
else
{
int gapz = abs(zque.top().val-0);
int idz = zque.top().id;
int gapf = abs(fque.top().val-0);
int idf = fque.top().id;
if(gapz<gapf)
{
a[idz] += x;
zque.pop();
node nw;
nw.id = idz;
nw.val = a[idz];
zque.push(nw);
}
else
{
a[idf] -= x;
fque.pop();
node nw;
nw.id = idf;
nw.val = a[idf];
fque.push(nw);
}
}
}
k--;
}
for(int i = 0;i<n;i++)
{
cout << a[i] << " ";
}
cout << endl;
return 0; }

参考文章:

木流牛马,D. Maxim and Array,https://www.cnblogs.com/thunder-110/p/9340279.html

上一篇:CodeForces 721D Maxim and Array


下一篇:细数Android开源项目中那些频繁使用的并发库中的类