题目链接:http://codeforces.com/problemset/problem/721/D

D. 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 

题解:

1.首先在输入时,统计负数的个数,目的是知道初始状态的乘积是正数(包括0)还是负数。

2.如果乘积为正数,那么就需要减小某个数的绝对值,使其改变符号, 而且步数越少越好,由此推出:减少绝对值最小的那个数的绝对值,可以最快改变符号,使得乘积变为负数。

3.如果乘积已经为负,那么就需要增加某个数的绝对值, 使得乘积的绝对值尽可能大, 根据基本不等式: a+b>=2*根号(a*b),若要a*b的值最大,则a==b。 可以得出结论:当a与b的差值越小时,a*b越大。或者可以自己手动推算一遍, 也可以得出这个结论。由此推出:增加绝对值最小的那个数的绝对值,使得乘积的绝对值尽可能大。

4.总的来说:就是需要对绝对值最小的数进行操作。当乘积为正或为0时, 减小其绝对值,直到符号改变; 当乘积为负时, 增加其绝对值, 使其乘积的绝对值尽可能大。 用优先队列维护。

学习之处: 

a+b=常数, 当a与b的差值越小时,a*b越大(a*b>=0)。

这里的a*b,可以假设a为绝对值最小的那个数, b为其他数的绝对值的乘积。所以这个结论也适用于多个数的乘积(将多个转为2个)。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <algorithm>
using namespace std;
#define ms(a, b) memset((a), (b), sizeof(a))
#define eps 0.0000001
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+7;
const int maxn = 2e5+10; struct node
{
LL v, s, pos;
bool operator<(const node&x)const{
return v>x.v;
}
};
priority_queue<node>q;
LL a[maxn], n, k, x, flag; void init()
{
scanf("%lld%lld%lld",&n, &k, &x);
while(!q.empty()) q.pop();
flag = 0;
for(int i = 1; i<=n; i++)
{
node e;
scanf("%lld",&a[i]);
e.v = abs(a[i]);
e.s = (a[i]<0);
e.pos = i;
q.push(e); if(a[i]<0) flag = !flag;
}
} void solve()
{
while(k--)
{
node e = q.top();
q.pop();
if(!flag)
{
e.v -= x;
if(e.v<0)
{
e.v = -e.v;
e.s = !e.s;
flag = !flag;
}
}
else
{
e.v += x;
}
a[e.pos] = e.v;
if(e.s) a[e.pos] = -a[e.pos];
q.push(e);
}
for(int i = 1; i<=n; i++)
printf("%lld ",a[i]);
putchar('\n');
} int main()
{
// int T;
// scanf("%d",&T);
// while(T--)
{
init();
solve();
}
return 0;
}

Codeforces Round #374 (Div. 2) D. Maxim and Array —— 贪心的更多相关文章

  1. Codeforces Round #374 (Div. 2) D. Maxim and Array 贪心

    D. Maxim and Array 题目连接: http://codeforces.com/contest/721/problem/D Description Recently Maxim has ...

  2. Codeforces Round #374 (Div. 2) D. Maxim and Array 线段树+贪心

    D. Maxim and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. Codeforces Round #374 (Div. 2) D. Maxim and Array

    传送门 分析:其实没什么好分析的.统计一下负数个数.如果负数个数是偶数的话,就要尽量增加负数或者减少负数.是奇数的话就努力增大每个数的绝对值.用一个优先队列搞一下就行了. 我感觉这道题的细节极为多,非 ...

  4. Codeforces Round #297 (Div. 2)C. Ilya and Sticks 贪心

    Codeforces Round #297 (Div. 2)C. Ilya and Sticks Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: xxx  ...

  5. Codeforces Round #374 (div.2)遗憾题合集

    C.Journey 读错题目了...不是无向图,结果建错图了(喵第4样例是变成无向就会有环的那种图) 并且这题因为要求路径点尽可能多 其实可以规约为限定路径长的拓扑排序,不一定要用最短路做 #prag ...

  6. Codeforces Round #374 (Div. 2) A B C D 水 模拟 dp+dfs 优先队列

    A. One-dimensional Japanese Crossword time limit per test 1 second memory limit per test 256 megabyt ...

  7. 拓扑序+dp Codeforces Round #374 (Div. 2) C

    http://codeforces.com/contest/721/problem/C 题目大意:给你有向路,每条路都有一个权值t,你从1走到n,最多花费不能超过T,问在T时间内最多能访问多少城市? ...

  8. Codeforces Round #374 (Div. 2) C. Journey DP

    C. Journey 题目连接: http://codeforces.com/contest/721/problem/C Description Recently Irina arrived to o ...

  9. Codeforces Round #374 (Div. 2) B. Passwords 贪心

    B. Passwords 题目连接: http://codeforces.com/contest/721/problem/B Description Vanya is managed to enter ...

随机推荐

  1. 串口VMIN VTIME 详解

    原文地址: 以前跟着做过VxWorks的开发,主要通信方式是串口,因为底层BSP包已经做好了,串口通信非常简单.后来接触Linux,在一块OK6410上跑Linux串口通信,才发现原来天真的以为甚是简 ...

  2. idea没有subversion问题

    问题描述:idea导入svn项目,但点击项目文件右键没有找到subversion选项.同时,idea界面底部没有version control菜单. 解决方法:原因是idea没有启动版本控制.点击id ...

  3. Java---详解方法传值问题

    过程解析: 1.首先执行int[] arr={3,5,6,1,7,9,0},遇到数组先执行等式右边的,{3,5,6,1,7,9,0}会在堆内存中开辟一块空间,分成7小块,下标分别从0~6,先进行系统初 ...

  4. SVG动画基础篇

    参考资料: http://www.w3school.com.cn/svg/index.asp https://msdn.microsoft.com/zh-cn/library/gg193979  gi ...

  5. Direct2D教程(一)Direct2D已经来了,谁是GDI的终结者?

    什么是Direct2D 一言以蔽之,就是Windows 7平台上的一个2D图形API,可以提供高性能,高质量的2D渲染.大多数人对Direct2D可能都比较陌生,以至于我之前在论坛上提到这个词的时候, ...

  6. yii框架:CDbConnection failed to open the DB connection: could not find driver的解决的方法

    这个问题是由于php中缺少pdo mysql造成的. 解决方法是为php加入此扩展.前往你最早的php安装文件,进入ext/pdo_mysql/文件夹下,然后./configure --with-ph ...

  7. intellij idea 提示找不到default activivty

      更换环境之后 ,intellij idea 提示找不到默认的activity.   而查看源代码. 在代码中明显已经设置了默认activity了. 后来发现.程序中有个库工程中的AndroidMe ...

  8. win10拷贝文件卡顿的问题-竟然是winrar搞的

    win10拷贝文件卡顿的问题-竟然是winrar搞的 学习了: http://www.w10zj.com/Win10xy/Win10xf_3378.html 没想到你竟然是这样的WinRAR 去除了s ...

  9. 网站的根目录下有一个文件robots.txt ,它是啥?

    我相信很多人有过这个疑问,这个robots文件是干嘛的? 我想问,各位搜索淘宝时,是否发现(禁止爬虫抓取提供快页) 关于详细语法,请看:http://zhidao.baidu.com/question ...

  10. Linux基础(4)-硬盘分区、格式化及文件系统的管理、软件包的管理、yum管理RPM包和python的源码安装

    一: 1)  开启Linux系统前添加一块大小为15G的SCSI硬盘 2)  开启系统,右击桌面,打开终端 3)  为新加的硬盘分区,一个主分区大小为5G,剩余空间给扩展分区,在扩展分区上划分1个逻辑 ...