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;
}