标签:ons 交换 ring 开始 min swa time i++ ssi
You are given 2 arrays a and b, both of size n. You can swap two elements in b at most once (or leave it as it is), and you are required to minimize the value
Find the minimum possible value of this sum.
大意:有两个大小为\(n\)的数组\(a\)和\(b\),交换数组\(b\)中的任意两个元素至多1次,使\(\sum_i|ai?bi|\)最小。\(n\le 2\cdot 10^5\),\(a_i,b_i\le10^9\)。
设一开始\(\sum_i|ai?bi|=tot\),交换\(b_i,b_j\),答案变为
所以最大化\(|a_i-b_i|+|a_j-b_j|-|a_i-b_j|-|a_j-b_i|\)就可以了。
固定\(i\)。为了拆掉绝对值符号,对\(a_j,b_i\)和\(b_j,a_i\)的大小关系分成\(2\times 2=4\)类,然后分别处理。
例如,当\(a_j\ge b_i\)且\(b_j\le a_i\),
对符合条件的\(j\)求括号内的部分的最大值,最后加上和\(i\)有关的部分就可以了。
对其它情况,处理方法几乎没有区别。我用分治方法离线查找最大值,一共需要做四次,实现起来有点繁琐。。还好代码不算长qwq
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <math.h>
#include <cstring>
#include <time.h>
#include <complex>
#include <algorithm>
#include <queue>
#include <stack>
#include <unordered_map>
#include <set>
#include <bitset>
#pragma warning(disable:4996)
#define PII std::pair<long long, long long>
#define PTT std::pair<tree *, tree *>
template<typename T> T min(T x, T y)
{
return x < y ? x : y;
}
template<typename T> T max(T x, T y)
{
return x > y ? x : y;
};
const long long INF = 200000000500000;//;// autojs.org
const long long mod = 998244353;//1000000007;//
const int MAXN = 400005;
struct data {
int id;
PII p;
data(int ID = 0, PII P = { 0,0 }) { id = ID, p = P; }
};
struct Solve {
int N;
data a[MAXN];
bool (*cmp1)(const data &, const data &);
bool (*cmp2)(const data &, const data &);
long long (*val)(data &);
long long ans[MAXN];
Solve() {}
Solve(long long *x, long long *y, int n, bool (*c1)(const data &, const data &)
, bool (*c2)(const data &, const data &), long long (*va)(data &))
{
cmp1 = c1, cmp2 = c2, val = va;
N = 2 * n;
for (int i = 1; i <= n; i++)
a[i] = data(i, { x[i], y[i] });
for (int i = n + 1; i <= 2 * n; i++)
a[i] = data(i, { y[i - n], x[i - n] });
std::sort(a + 1, a + N + 1, cmp1);
for (int i = 1; i <= N; i++)
ans[i] = -INF;
}
void solve(int L, int R)
{
static data tmp[MAXN];
if (L == R)
return;
int mid = (L + R) / 2;
solve(L, mid);
solve(mid + 1, R);
int i = L, j = mid + 1, k = L;
long long mx = -INF;
while (k <= R)
{
if (i <= mid && (j > R || cmp2(a[i], a[j])))
{
if (a[i].id <= N / 2)
mx = max(mx, val(a[i]));
tmp[k++] = a[i++];
}
else
{
ans[a[j].id] = max(ans[a[j].id], mx);
tmp[k++] = a[j++];
}
}
for (int i = L; i <= R; i++)
a[i] = tmp[i];
}
};
long long mabs(long long x) { return x > 0 ? x : -x; }
bool cmp11(const data &x, const data &y) { if (x.p.first == y.p.first)return x.id < y.id; return x.p.first > y.p.first; }
bool cmp12(const data &x, const data &y) { if (x.p.second == y.p.second)return x.id < y.id; return x.p.second < y.p.second; }
bool cmp21(const data &x, const data &y) { if (x.p.first == y.p.first)return x.id < y.id; return x.p.first > y.p.first; }
bool cmp22(const data &x, const data &y) { if (x.p.second == y.p.second)return x.id < y.id; return x.p.second > y.p.second; }
bool cmp31(const data &x, const data &y) { if (x.p.first == y.p.first)return x.id < y.id; return x.p.first < y.p.first; }
bool cmp32(const data &x, const data &y) { if (x.p.second == y.p.second)return x.id < y.id; return x.p.second > y.p.second; }
bool cmp41(const data &x, const data &y) { if (x.p.first == y.p.first)return x.id < y.id; return x.p.first < y.p.first; }
bool cmp42(const data &x, const data &y) { if (x.p.second == y.p.second)return x.id < y.id; return x.p.second < y.p.second; }
long long val1(data &x) { return mabs(x.p.first - x.p.second) - x.p.first + x.p.second; }
long long val2(data &x) { return mabs(x.p.first - x.p.second) - x.p.first - x.p.second; }
long long val3(data &x) { return mabs(x.p.first - x.p.second) + x.p.first - x.p.second; }
long long val4(data &x) { return mabs(x.p.first - x.p.second) + x.p.first + x.p.second; }
int N;
long long a[MAXN], b[MAXN], tot;
Solve S[4];
void init()
{
scanf("%d", &N);
for (int i = 1; i <= N; i++)
scanf("%lld", a + i);
for (int i = 1; i <= N; i++)
scanf("%lld", b + i), tot += mabs(a[i] - b[i]);
S[1 - 1] = Solve(a, b, N, cmp11, cmp12, val1);
S[2 - 1] = Solve(a, b, N, cmp21, cmp22, val2);
S[3 - 1] = Solve(a, b, N, cmp31, cmp32, val3);
S[4 - 1] = Solve(a, b, N, cmp41, cmp42, val4);
}
void solve()
{
const int c[4][2] = { {-1,1},{1,1},{1,-1},{-1,-1} };
long long ans = 0;
for (int i = 0; i < 4; i++)
{
S[i].solve(1, S[0].N);
for (int j = 1; j <= N; j++)
ans = max(ans, S[i].ans[j + N] + mabs(a[j] - b[j])
+ c[i][0] * a[j] + c[i][1] * b[j]);
}
printf("%lld\n", tot - ans);
}
int main()
{
init();
solve();
return 0;
}
codeforces 1513F. Swapping Problem
标签:ons 交换 ring 开始 min swa time i++ ssi
原文地址:https://www.cnblogs.com/blogofddw/p/14673297.html