题目背景

HJZ 有很多玩具。他最喜欢玩的玩具是一个可以变化的数组。

题目描述

HJZ 的数组初始时有 n 个元素。他可以把一个位置上的数加上或减去一个固定的

数 x。

一天 LJZ 和 HZY 来 HJZ 家玩。LJZ 突发奇想,提出了一个问题:如何在给定的

操作步数内最小化数组所有元素的乘积呢?

HJZ 百思不得其解,但是他想博得 HZY 的好感,就把这个问题交给你啦 ~

由于最小乘积可能很小,HJZ 只需要你给出

. 最 . 小 . 乘 . 积 . 对 10^9 + 7

. 取 . 模的结果。

. 请 . 注 . 意 . 一 . 个 . 数 . 对 p . 取 . 模 . 的 . 结 . 果 . 一 . 定 . 是 . 非 . 负 . 数, . 即 . 你 . 输 . 出 . 的 . 结 . 果 ans

. 要 . 满 . 足 0 ≤ ans < 10^ 9 + 7 。

输入输出格式

输入格式:

从文件 array.in 中读入数据。

第一行三个整数 n,k, x 分别表示数组元素个数、最多操作次数和每次操作的数。

第二行 n 个整数 a 1 ,a 2 ,...,a n 表示数组初始时的元素。

输出格式:

输出到文件 array.out 中。

一行一个在 [0,10 9 + 7) 范围内的整数,表示最小乘积的绝对值对 10 9 + 7 取模的

结果。

输入输出样例

输入样例#1:

3 2 7
5 4 2
输出样例#1:

999999732
【样例 1 解释】
最多可以进行两次操作,每次把一个位置 +7 或 −7 。
最优策略是将数组第二个元素 +7 ,第三个元素 −7 ,得到新的数组 5 11 − 5 ,乘
积为 5 × 11 × (−5) = −275 ,模 10 9 + 7 的结果是 999999732 。
输入样例#2:

5 3 1
5 4 3 5 5
输出样例#2:

0
【样例 2 解释】
只能把一个位置 +3 或 −3 ,把第三个位置 −3 最优,乘积为 0 。
【子任务】
对于所有测试点,1 ≤ n,k ≤ 2 × 10^5 ,1 ≤ x ≤ 10^9 ,|a i | ≤ 10^9 。
分析:数据很大,不可能dp,稍微做过一点贪心题的人能够一眼看出这道题就是用贪心做,但是具体怎么贪心比较难想,如果我们能让乘积变成负数是最好的,如果当前的乘积是正数,那么我们要先用最少的步数让乘积变成负数,这个时候操作绝对值最小的数让它变成符号相反的数就能使乘积变成负数了.
要使每次操作的贡献最大,肯定是操作绝对值最小的数,如果绝对值最小的数是正数,就让他增加x,否则就让它减少x,乘积还是负数,而且每一次的贡献是最大的,所以答案一定是最优的,每次找绝对值最小的数用优先队列.
需要注意对于0的处理.
#include <cstdio>
#include <functional>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath> using namespace std; const long long mod = ; long long n, k, x,ans = ,cnt;
priority_queue <long long> q1; //存负数
priority_queue <long long, vector<long long>, greater<long long> >q2; //存正数 void jian()
{
long long y = q2.top();
q2.pop();
while (k && y)
{
k--;
y -= x;
if (y <= )
{
q1.push(y);
return;
}
}
q2.push(y);
} void jia()
{
long long y = q1.top();
q1.pop();
while (k && y <= )
{
k--;
y += x;
if (y > )
{
q2.push(y);
return;
}
}
q1.push(y);
} int main()
{
scanf("%lld%lld%lld", &n, &k, &x);
for (int i = ; i <= n; i++)
{
long long t;
scanf("%lld", &t);
if (t <= )
{
q1.push(t);
cnt++;
}
else
q2.push(t);
}
//先让乘积变成负数
if (cnt % == )
{
if (cnt == )
jian();
else
if (cnt == n)
jia();
else
if (abs(q1.top()) < abs(q2.top()))
jia();
else
jian();
}
for (int i = ; i <= k; i++)
{
long long t1, t2;
if (!q1.empty())
t1 = q1.top();
else
t1 = -; if (!q2.empty())
t2 = q2.top();
else
t2 = ;
if (abs(t1) > abs(t2))
{
q2.pop();
t2 += x;
q2.push(t2);
}
else
{
q1.pop();
t1 -= x;
q1.push(t1);
}
}
while (!q1.empty())
{
ans = (ans * (q1.top() % mod)) % mod;
q1.pop();
}
while (!q2.empty())
{
ans = (ans * (q2.top() % mod)) % mod;
q2.pop();
}
while (ans < )
ans += mod;
printf("%lld\n", ans); return ;
}


常州模拟赛d7t2 数组的更多相关文章

  1. 常州模拟赛d7t3 水管

    分析:第一问还是很好做的,关键是怎么做第二问.我们可以每次删掉最小生成树上的一条边,然后再求一次最小生成树,看边权和大小和原来的是不是一样的,不过这个做法效率很低. 考虑Kruskal算法的原理,每次 ...

  2. 常州模拟赛d6t3 噪音

    FJ有M个牛棚,编号1至M,刚开始所有牛棚都是空的.FJ有N头牛,编号1至N,这N头牛按照编号从小到大依次排队走进牛棚,每一天只有一头奶牛走进牛棚.第i头奶牛选择走进第p[i]个牛棚.由于奶牛是群体动 ...

  3. 常州模拟赛d5t2 mogician

    分析:一个暴力的思想是枚举g,然后枚举每个数ai,看能不能符合要求,这样复杂度是O(nA)的,直接T掉了.也没什么其他的办法了,在暴力的基础上优化一下,优化的关键是要如何快速统计出不满足要求的数的个数 ...

  4. 常州模拟赛d4t3 字符串划分

    题目描述 给你一串由小写字母组成的字符串,希望你把它划分成一些小段,使得每一小段字符串中的字母 都不相同,并且希望分的段数尽量少. 然后,把这些小段按字典序排序后输出,中间由一个空格分隔. 例如:字符 ...

  5. 常州模拟赛d4t1 立方体

    题目描述 立方体有 6 个面,每个面上有一只奶牛,每只奶牛都有一些干草.为了训练奶牛的合作精神,它 们在玩一个游戏,每轮:所有奶牛将自己的干草分成 4 等份,分给相邻的 4 个面上的奶牛. 游戏开始, ...

  6. 常州模拟赛d3t3 两只怪物心心相印

    题目背景 从前我是一位无名的旅人,旅途中我得到了某样东西:贤者之石.我因此得到悠久的时光和漂泊的生命.1897年冬天,我一时兴起舍弃了旅人的生活. 贤者之石创造出来的,是货真价实的黄金.我的名声传遍了 ...

  7. 常州模拟赛d2t2 小X的密室

    题目描述 密室中有 N 个房间,初始时,小 X 在 1 号房间,而出口在 N 号房间. 密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会 单向地 创造一条从房间 X 到房间 Y 的通道.另 ...

  8. 常州模拟赛d8t2 绘画

    分析:考虑记录每个坐标上每个颜色出现了几次,并由此算出每个颜色在这个坐标上的贡献.答案肯定是原图的答案扣去矩形的答案,再加上那个矩形同种颜色的贡献,这里的答案指的是Σdis.我们先要记录每个颜色在各个 ...

  9. 常州模拟赛d8t1 友好数对

    分析:其实就是问你有多少对a,b有且仅有两位不相同.我们可以先枚举这两位,对应ai枚举一位,对应bi枚举一位,如果ai^(1<<x) == bi^(1<<y),证明恰好有两位不 ...

随机推荐

  1. url中传参数为中文的转码与解码解决方法

    1.转码 中文为 “你好”  var ProjectName = encodeURI(encodeURI("你好"));,如下图所示 跳转页面  window.location.h ...

  2. 获取openid [微信小程序]

    public function wxapi(){ $data=$this->requestdata(); if(!$data['code']) exit(json_encode(array('s ...

  3. centos 安装sysbench

    安装sysbench 下载并且解压 shell> wget https://github.com/akopytov/sysbench/archive/1.0.zip -O "sysbe ...

  4. Linux命令(008) -- yum

    yum命令(全称为Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指定的服务器自动下 ...

  5. JSON基础 JS操作JSON总结

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...

  6. SQL编程语句

    视图 视图就是我们查询出来的虚拟表创建视图:create view 视图名 as SQL查询语句,分组,排序,in 等都不能写视图的用法: select * from 视图名 SQL编程 定义变量:d ...

  7. java 8 stream使用

    使用stream代替循环的方案 1.定义一个Article类包括标题.作者.标签 private class Article { private final String title; private ...

  8. Mysql5.7多源复制,过滤复制一段时间后增加复制一个库的实现方法

    多源复制如果是整个实例级别的复制,那不存在下面描述的情况. 如果是对其中一个或多个主实例都是过滤复制,并且运行一段时间后,想在这个源上再增加一个库怎么实现?   主1:192.168.1.10 330 ...

  9. Extensions can add new functionality to a type, but they cannot override existing functionality.

    Extensions can add new functionality to a type, but they cannot override existing functionality.

  10. MFC_2.1使用单选和多选框

    使用单选和多选框 单选 1.拖控件 设置名字,CTRL+D设置顺序,属性设置第一个GROUP为TRUE: 2.设置第一个按钮绑定变量为 值 INT型 名称m_RadioIndxe; 3.设置单击响应内 ...