题目链接
题意:现给你两个数组A,B,你需要交换k次b内元素,问交换后 ∑ 1 n \sum_1^n ∑1nabs(ai-bi)最大为多少
解析:
当没有k的限制时:
①如果ai>=bi,则abs(ai-bi)=ai-bi,即A,B数组中有n个元素做被减数,n个做减数,ans = ∑ 1 n 被 减 数 \sum_1^n被减数 ∑1n被减数- ∑ 1 n 减 数 \sum_1^n减数 ∑1n减数,要获得最大的ans,则被减数应该是A,B中最大的n个元素,减数为A,B中最小的n个元素,用C数组表示被减数元素集合,D数组表示减数元素集合,且显然有sizeof©=sizeof(D)
②那么需要交换怎样的bi,bj呢?有分析①易知我们要使减数与被减数一一配对,则当a[i],b[i]属于C,而a[j],b[j]属于D时,我们要交换b[i]和b[j];
当存在k限制且n>2时:
①若k>=sizeof©,我们通过sizeof©次交换可以使减数与被减数一一配对,剩下的k次我们可以交换同为减数或被减数的元素,这样不会导致结果变劣
②若k
当存在k限制且n等于2时:
①此时当k>=sizeof©时,交换使减数与被减数一一配对后,我们再进行交换是会影响到结果的,可能导致结果变劣,比如n=2,k=4,初始ans不为最大时,我们交换一次后ans为最大值,我们还要交换三次,但我们只有一种交换方法,到最后数组与初始数组一致
②所以当n为2时答案即为b1,b2交换k%2次的结果
AcCode
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int N = 5e5 + 100;
int a[N], b[N], arr[N << 1], c[N], d[N], e[N], f[N];
map<int, int> rmap;
vector<int> vec1, vec2;
inline int mabs(int a) { return (a >= 0) ? a : -a; }
inline int min(int a, int b) { return (a >= b) ? b : a; }
inline int max(int a, int b) { return (a >= b) ? a : b; }
signed main() {
/*ios::sync_with_stdio(false);
cin.tie(0);*/
int n, cnt = 0, k;
ll ans = 0;
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), arr[++cnt] = a[i];
for (int j = 1; j <= n; j++) scanf("%d", &b[j]), arr[++cnt] = b[j], ans = ans + 1ll * mabs(a[j] - b[j]);
if (n == 2) {
if (k % 2 == 0) {
printf("%lld\n", ans);
//cout << ans << endl;
}
else if (k & 1) {
//cout << abs(a[2] - b[1]) + abs(a[1] - b[2]) << endl;
printf("%d\n", mabs(a[2] - b[1]) + mabs(a[1] - b[2]));
}
return 0;
}
sort(arr + 1, arr + 1 + cnt, greater<int>());//nlogn
int maxup = 0;
int fcnt = 0, ecnt = 0;
int sign = arr[cnt / 2];
for (int i = cnt / 2; i && arr[i] == sign; i--) maxup++;
for (int i = 1; i <= n; i++) {
if (a[i] > sign) c[i] = a[i];
else if (a[i] == sign && maxup) maxup--, c[i] = a[i];
else c[i] = -a[i];
}
for (int i = 1; i <= n; i++) {
if (b[i] > sign) d[i] = b[i];
else if (b[i] == sign && maxup) maxup--, d[i] = b[i];
else d[i] = -b[i];
}
for (int i = 1; i <= n; i++) {
if (a[i] == c[i] && b[i] == d[i]) {
//vec1.push_back(min(a[i], b[i]));
e[++ecnt] = min(a[i], b[i]);
}
else if (a[i] == -c[i] && b[i] == -d[i]) {
//vec2.push_back(max(a[i], b[i]));
f[++fcnt] = max(a[i], b[i]);
}
}
sort(e + 1, e + 1 + ecnt, greater<int>());
//sort(vec1.begin(), vec1.end(), greater());
sort(f + 1, f + 1 + fcnt);
//sort(vec2.begin(), vec2.end());
if (ecnt <= k) {
for (int i = 1; i <= ecnt; i++) {
ans = ans + 2ll * (e[i] - f[i]);
}
}
else {
for (int i = 1; i <= k; i++) ans = ans + 2ll * (e[i] - f[i]);
}
printf("%lld\n", ans);
}