这些性质基于我的做法,但是本人水平有限,无法证明。所以请大佬证明或 hack。
做法:先按照 1 n 2 (n - 1) 3 (n - 2)...(这里的数表示排名)这样构造得到一个序列。
那么答案序列一定可以是该序列的一个奇数长度的前缀反转。详细可以看代码,不过我认为描述已经很清楚了。
int n, a[MAXN], b[MAXN], c[MAXN]; ll p, q, ans;
ll sum[MAXN], sum2[MAXN];
il ll cal() {
ll ans = 0;
rep1(i, 1, n - 1) ans += abs(p * a[i] - q * a[i + 1]);
ans += abs(p * a[n] - q * a[1]);
return ans;
}
int main() {
read(n, p, q); rer(i, 1, n, a);
sort(a + 1, a + 1 + n);
int l = 1, r = n;
rep1(i, 1, n) {
if (i & 1) b[i] = a[l++];
else b[i] = a[r--];
} memcpy(a, b, sizeof(int) * (n + 1));
ll init = ans = cal();
auto lnk = [&](int x, int y) {return abs(a[x] * p - a[y] * q);};
rep1(i, 1, n - 1) sum[i] = sum[i - 1] + lnk(i, i + 1);
rep1(i, 2, n) sum2[i] = sum2[i - 1] + lnk(i, i - 1);
int t = 0;
rep1(k, 1, n - 1) {
ll now = init - sum[k - 1] + sum2[k] + lnk(1, k + 1) + lnk(n, k) - lnk(k, k + 1) - lnk(n, 1);
if (now > ans) ans = now, t = k;
++k;
}
printf("%lld\n", ans);
reverse(a + 1, a + 1 + t);
rep1(i, 1, n) printf("%d ", a[i]);
rout;
}