ABC416D
问题简化
转化为由\(A, B\) 中的元素组成的二元组,使得两个元素的和取模 \(m\) 的和最小
Slove
贪心的,先尽可能的组成更多的二元组使得二元组亮相的和为 \(m\)
readf(&n), readf(&m);
ll cntA = 0, cntB = 0, ans = 0;
std::multiset<ll> a, b, c;
for (size_t i = 1; i <= n; i++) {
ll val = readf<ll>();
a.insert(val);
c.insert(m - val);
}
//现在的s
for (size_t i = 1; i <= n; i++) {
ll val;
readf(&val);
if (c.count(val)) {
a.erase(a.find(m - val));
c.erase(val);
}
else {
b.insert(val);
}
}
对于剩下的元素,希望二元组的和取模 \(m\) 尽可能的小
贪心的,先把较大的解决掉, 比较大的比小的更麻烦。
从 $A, B $ 中取一个最大值
对于最大值由2中解决方式
-
让其加上一个值,使得和超过\(m\), 取模让其变小
-
让其加上一个值,使得和尽量小
#define _FREAD true
#define MAX_INF 1e18
#define MAX_NUM_SIZE 35
#define MAXN (size_t)(3e5+5)
typedef long long int ll;
typedef unsigned long long int ull;
//快读函数声明
template< typename Type >
inline Type readf(Type* p = nullptr);
//快速输出函数
template<typename Type>
inline void writef(Type x);
ll arrA[MAXN], arrB[MAXN];
ll t, n, m;
inline void slove() {
readf(&n), readf(&m);
ll cntA = 0, cntB = 0, ans = 0;
std::multiset<ll> a, b, c;
for (size_t i = 1; i <= n; i++) {
ll val = readf<ll>();
a.insert(val);
c.insert(m - val);
}
//现在的s
for (size_t i = 1; i <= n; i++) {
ll val;
readf(&val);
if (c.count(val)) {
a.erase(a.find(m - val));
c.erase(val);
}
else {
b.insert(val);
}
}
ll apos = cntA, bpos = cntB;
while (!a.empty()) {
std::multiset<ll>::iterator aend = a.end(), bend = b.end();
--aend, --bend;
if ((*aend) > (*bend)) {
//现在a最大的大于b最大
ll val = m - *(aend), temp = 0;
std::multiset<ll>::iterator p = b.lower_bound(val);
if (p == b.end()) {
temp += *b.begin();
b.erase(b.begin());
}
else {
if ((*p + *aend) % m < (*b.begin() + *(aend)) % m) {
temp += *p;
b.erase(p);
}
else {
temp += *b.begin();
b.erase(b.begin());
}
}
temp += *(aend);
temp %= m;
ans += temp;
a.erase(aend);
}
else {
//现在a最大的大于b最大
ll val = m - *(bend), temp = 0;
std::multiset<ll>::iterator p = a.lower_bound(val);
if (p == a.end()) {
temp += *a.begin();
a.erase(a.begin());
}
else {
if ((*p + *(bend)) % m < (*a.begin() + *(bend)) % m) {
temp += *p;
a.erase(p);
}
else {
temp += *a.begin();
a.erase(a.begin());
}
}
temp += *(bend);
temp %= m;
ans += temp;
b.erase(bend);
}
}
printf("%lld\n", ans);
return;
}
int main() {
#ifdef _FREOPEN
freopen("input.txt", "r", stdin);
#endif // _FREOPEN
#ifdef _RUN_TIME
clock_t start = clock();
#endif // _RUN_TIME
readf(&t);
while (t--) {
slove();
}
#ifdef _RUN_TIME
printf("The running duration is not less than %ld ms\n", clock() - start);
#endif // _RUN_TIME
return 0;
}

浙公网安备 33010602011771号