D是一个贪心题目,由平方差公式我们可以知道和一定的情况下,两数越接近他们的乘积越大,所以我们可以将数列排序后划分为两部分,大数放入大根堆,小数放入小根堆,每次取出两个堆的堆顶,判断修改后的乘积是否更优,如果更优,则再次加入堆组,否则立即退出,因为此刻再运算一定不会得到更优的值了,同样负数也可以同时进行判断,代码如下。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int N = 3e5 + 10;
int n, m, k;
ll q[N];
priority_queue<ll, vector<ll>, greater<ll>> great;
priority_queue<ll, vector<ll>> les;
int main() {
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i ++ ) scanf("%lld", q + i);
sort(q + 1, q + n + 1);
for (int i = 1; i <= n; i ++ )
if (i <= n / 2) great.push(q[i]);
else les.push(q[i]);
ll mid = q[n / 2];
for (int i = 1; i <= k; i ++ ) {
ll maxx = great.top(), minn = les.top();
if ((maxx + m) * (minn - m) < maxx * minn) break;
maxx += m, minn -= m;
great.pop(), les.pop();
if (maxx >= mid) les.push(maxx), great.push(minn);
else les.push(minn), great.push(maxx);
}
ll ans = 1;
while (great.size()) ans = ans * great.top() % mod, great.pop();
while (les.size()) ans = ans * les.top() % mod, les.pop();
printf("%lld", ans);
return 0;
}