# 「NOI2019d1t3」序列

## $$Solution$$：

$$S - A_i \ (1, a_i)$$$$A_i - B_i \ (1, 0)$$$$B_i - R \ (1, b_i)$$$$R - T \ (K, 0)$$

$$A_i - P \ (1, 0)$$$$P - Q \ (K - L, 0)$$$$Q - B_i \ (1, 0)$$

1.选位置相同的一对；
2.选 $$A$$ 中的最大值 $$A_i$$$$B$$$$A_j$$ 已经被选过的最大值 $$B_j$$，反之同理。

## $$Source$$

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 1e6 + 5;

int n, K, L;
int a[N], b[N];

typedef std::pair<int, int> pii;
std::priority_queue<pii> q1, q2, h1, h2, q;
int vis1[N], vis2[N];

void prep() {
memset(vis1, 0, sizeof(vis1));
memset(vis2, 0, sizeof(vis2));
while (!q1.empty()) q1.pop();
while (!q2.empty()) q2.pop();
//printf("%d\n", h1.size());
while (!h1.empty()) h1.pop();
while (!h2.empty()) h2.pop();
while (!q.empty()) q.pop();
for (int i = 1; i <= n; ++i) {
q1.push(pii(a[i], i)), q2.push(pii(b[i], i));
q.push(pii(a[i] + b[i], i));
}
}

long long work() {
long long ret = 0;
int now = 0;
for (int i = 1; i <= K; ++i) {
if (now < K - L) {
int u, v;
while (!q1.empty()) {
u = q1.top().second; q1.pop();
if (!vis1[u])
break;
}
while (!q2.empty()) {
v = q2.top().second; q2.pop();
if (!vis2[v])
break;
}
if (u != v) {
if (!vis2[u])
h2.push(pii(b[u], u));
if (!vis1[v])
h1.push(pii(a[v], v));
}
if (vis2[u] && vis1[v])
--now;
else if (!vis2[u] && !vis1[v] && u != v)
++now;
vis1[u] = vis2[v] = 1;
ret += a[u] + b[v];
} else {
int u1 = 0, u2 = 0, s1 = 0;
while (!q1.empty()) {
u1 = q1.top().second;
if (!vis1[u1])
break;
q1.pop();
}
while (!h2.empty()) {
u2 = h2.top().second;
if (!vis2[u2])
break;
h2.pop();
}
if (u2 && !vis2[u2])
s1 = a[u1] + b[u2];

int v2 = 0, v1 = 0, s2 = 0;
while (!q2.empty()) {
v2 = q2.top().second;
if (!vis2[v2])
break;
q2.pop();
}
while (!h1.empty()) {
v1 = h1.top().second;
if (!vis1[v1])
break;
h1.pop();
}
if (v1 && !vis1[v1])
s2 = a[v1] + b[v2];

int w = 0, s3 = 0;
while (!q.empty()) {
w = q.top().second;
if (!vis1[w] && !vis2[w])
break;
q.pop();
}
if (!vis1[w] && !vis2[w])
s3 = a[w] + b[w];

//printf("%d %d  %d %d  %d\n", u1, u2, v1, v2, w);
//printf("%d %d %d\n", s1, s2, s3);
if (w && s3 > s1 && s3 > s2) {
q.pop();
vis1[w] = vis2[w] = 1;
ret += s3;
} else if (s1 >= s3 && (s1 > s2 || (s1 == s2 && vis2[u1] > vis1[v2]))) {
q1.pop(), h2.pop();
vis1[u1] = 1, vis2[u2] = 1;
if (vis2[u1])
--now;
else
h2.push(pii(b[u1], u1));
ret += s1;
} else {
//printf("%d\n", h1.size());
//printf("%d %d %d\n", s1, s2, s3);
q2.pop(), h1.pop();
vis2[v2] = 1, vis1[v1] = 1;
if (vis1[v2])
--now;
else
h1.push(pii(a[v2], v2));
ret += s2;
}

}
//printf("%d %d\n", u, v);
}
return ret;
}

int main() {
//freopen("in", "r", stdin);
//freopen("out2", "w", stdout);
int tim = in();
while (tim--) {
n = in(), K = in(), L = in();
for (int i = 1; i <= n; ++i)
a[i] = in();
for (int i = 1; i <= n; ++i)
b[i] = in();
prep();
printf("%lld\n", work());
}
return 0;
}

posted @ 2020-05-28 18:55  15owzLy1  阅读(170)  评论(0编辑  收藏  举报