rt,应该是 O(nlogV)(V 是值域),但是 T 了 24 个点。
赛时提交。
#include <bits/stdc++.h>
#define _for(i, a, b) for (int i = (a); i <= (b); i ++ )
#define ll long long
using namespace std;
const int N = 2e5 + 5, M = 1e6 + 5;
const ll inf = (ll)2e18 + 5;
int n, K, V; ll ans; priority_queue<int> q;
struct Number { int a, b; } t[N];
struct Seg_Tree {
#define lc p << 1
#define rc p << 1 | 1
#define mid ((tr[p].l + tr[p].r) >> 1)
struct Tree { int l, r; ll val; } tr[M << 2];
inline int len(int p) { return tr[p].r - tr[p].l + 1; }
inline void push_up(int p) { tr[p].val = tr[lc].val + tr[rc].val; }
void build(int p, int l, int r) {
tr[p].l = l, tr[p].r = r, tr[p].val = 0;
if (l == r) return ;
build(lc, l, mid), build(rc, mid + 1, r), push_up(p);
}
void update(int p, int x, int k) {
if (x < 1 || x > V) return ;
if (len(p) == 1) { tr[p].val += k; return ; }
update(x <= mid ? lc : rc, x, k), push_up(p);
}
ll query(int p, int l, int r) {
if (l > r) return 0;
if (l <= tr[p].l && tr[p].r <= r) return tr[p].val;
ll res = 0;
if (l <= mid) res += query(lc, l, r);
if (r > mid) res += query(rc, l, r);
return res;
}
} T[2];
inline void solve() {
while (q.size()) q.pop();
cin >> n >> K, V = 0, ans = inf; int pos, cnt;
_for (i, 1, n) cin >> t[i].a;
_for (i, 1, n) cin >> t[i].b, V = max(V, t[i].b);
sort(t + 1, t + n + 1, [&] (Number u, Number v) { return u.a ^ v.a ? u.a < v.a : u.b < v.b; }), T[0].build(1, 1, V), T[1].build(1, 1, V);
_for (i, 1, K - 1) T[0].update(1, t[i].b, 1), T[1].update(1, t[i].b, t[i].b), q.push(t[i].b);
_for (i, K, n) {
T[0].update(1, t[i].b, 1), T[1].update(1, t[i].b, t[i].b);
if (q.empty() || q.top() > t[i].b) {
if (i > K) q.pop();
q.push(t[i].b);
}
pos = q.top(), cnt = T[0].query(1, 1, pos - 1), ans = min(ans, 1ll * t[i].a * (T[1].query(1, 1, pos - 1) + 1ll * pos * (K - cnt)));
}
cout << ans << "\n";
}
int main() {
ios :: sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T; cin >> T;
while (T -- ) solve();
return 0;
}