链接:戳这里
D. Maxim and Array
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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次操作
每次操作就是选择一个数+x || -x ,使得最后所有数的乘积最小
输出操作完之后的这n个数
思路:
首先我们可以贪心想到,只有奇数个负号的时候,答案会最有利
然后怎么去选择操作哪个数呢?
这个贪心也很常见,就是每次将当前绝对值最小的数+x使得与每个数的差距渐渐缩小
这样所有数绝对值的乘积才会最大
代码:
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
struct node{
ll v;
int id;
node(ll v=0,int id=0):v(v),id(id){}
bool operator < (const node &a) const{
return v>a.v;
}
};
priority_queue<node> qu;
int n,k;
ll x;
ll a[200100],b[200100],anw[200100];
void solve(){
for(int i=1;i<=n;i++) qu.push(node(b[i],i));
while(k){
node now=qu.top();
qu.pop();
k--;
qu.push(node(now.v+x,now.id));
}
while(!qu.empty()) {
node now=qu.top();
qu.pop();
b[now.id]=now.v;
}
}
int main(){
scanf("%d%d%lld",&n,&k,&x);
int num=0;
for(int i=1;i<=n;i++) {
scanf("%lld",&a[i]);
b[i]=abs(a[i]);
if(a[i]<0) num++;
}
if(num%2==0){
int pos=1;
for(int i=1;i<=n;i++){
if(b[i]<b[pos]) pos=i;
}
if(b[pos]-1LL*k*x>=0){
b[pos]-=1LL*k*x;
k=0;
} else {
if(a[pos]<0){
k-=b[pos]/x+1;
a[pos]+=1LL*(b[pos]/x+1)*x;
num--;
} else {
k-=b[pos]/x+1;
a[pos]-=1LL*(b[pos]/x+1)*x;
num++;
}
b[pos]=abs(a[pos]);
//for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
solve();
}
} else solve();
for(int i=1;i<=n;i++){
if(a[i]<0) anw[i]-=b[i];
else anw[i]=b[i];
}
for(int i=1;i<=n;i++) cout<<anw[i]<<" ";cout<<endl;
return 0;
}