#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define int long long #define mp make_pair #define pii pair #define fi first #define se second #define pb push_back const int MOD = 998244353;// const int FACTMAX = 2000005;// const int CATALANMAX = 1000005;// int fact[FACTMAX], invfact[FACTMAX], cat[CATALANMAX]; int expo(int a, int b){ int res=1; a%=MOD; while (b){ if (b&1)res=(res*a)%MOD; a=(a*a)%MOD; b>>=1; } return res; } int inv(int num){ return expo(num, MOD-2); } void initfact(){ fact[0]=1; for (int i=1; i=0; --i)invfact[i]=(invfact[i+1]*(i+1))%MOD; } int ncr(int n, int r){ if (n vals; node *cntst, *sumst; struct node{ int s, e, m, val, lazyset, lazyadd; node *l, *r; void create(){ if (l==nullptr){ l = new_node(s, m); r = new_node(m+1, e); } } void propagate(){ if (lazyset!=-1)val=lazyset*(e-s+1); val+=lazyadd*(e-s+1); if (s!=e && (lazyset!=-1 || lazyadd)){ if (l==nullptr)create(); if (lazyset!=-1){ l->lazyset=lazyset; r->lazyset=lazyset; l->lazyadd=r->lazyadd=0; } if (lazyadd){ l->lazyadd+=lazyadd; r->lazyadd+=lazyadd; } } lazyset=-1; lazyadd=0; } node(){} node(int S, int E){ s = S, e = E, m = (s+e)/2; val=lazyadd=0; lazyset=-1; l=r=nullptr; } void upset(int left, int right, int v){ propagate(); if (s==left && e==right)lazyadd=0, lazyset=v; else{ if (l==nullptr)create(); if (right<=m)l->upset(left, right, v); else if (left>m)r->upset(left, right, v); else l->upset(left, m, v), r->upset(m+1, right, v); r->propagate(), l->propagate(); val=l->val+r->val; } } void upadd(int left, int right, int v){ propagate(); if (s==left && e==right)lazyadd+=v; else{ if (l==nullptr)create(); if (right<=m)l->upadd(left, right, v); else if (left>m)r->upadd(left, right, v); else l->upadd(left, m, v), r->upadd(m+1, right, v); r->propagate(), l->propagate(); val=l->val+r->val; } } int query(int left, int right){ propagate(); if (s==left && e==right)return val; if (right<=m)return l->query(left, right); else if (left>m)return r->query(left, right); else return l->query(left, m)+r->query(m+1, right); } }; const int poolmax = 1601005 * 2; node pool[poolmax]; int poolptr; node* new_node(int s, int e){ pool[poolptr]=node(s, e); return &pool[poolptr++]; } node* build(int s, int e){ node* st = new_node(s, e); if (s!=e){ st->l=build(s, st->m); st->r=build(st->m+1, e); } return st; } int qry(node* st, int left, int right){ if (left>right)return 0; return st->query(left, right); } int get_pos(int v){ return lower_bound(vals.begin(), vals.end(), v)-vals.begin()+1; } int get_val(int pos){ return vals[pos-1]; } int kth(node* st, int k){ st->propagate(); if (st->s==st->e)return st->s; st->l->propagate(); if (st->l->val>=k)return kth(st->l, k); st->r->propagate(); return kth(st->r, k-st->l->val); } void add_pos(int pos, int delta){ if (!delta)return; cntst->upadd(pos, pos, delta); sumst->upadd(pos, pos, delta*get_val(pos)); } void clear_range(int left, int right){ if (left>right)return; cntst->upset(left, right, 0); sumst->upset(left, right, 0); } void remove_smallest(int k){ if (k<=0)return; cntst->propagate(); if (k>=cntst->val){ clear_range(1, (int)vals.size()); return; } int p = kth(cntst, k); int pref = qry(cntst, 1, p-1); clear_range(1, p-1); int rem = k-pref; if (rem)add_pos(p, -rem); } int remove_largest(int left, int right, int k){ if (left>right || k<=0)return 0; int total = qry(cntst, left, right); if (!total)return 0; if (k>=total){ int ret = qry(sumst, left, right); clear_range(left, right); return ret; } int keep = total-k; int before = qry(cntst, 1, left-1); int p = kth(cntst, before+keep); int pref = qry(cntst, left, p-1); int keep_at_p = keep-pref; int cntp = qry(cntst, p, p); int rem = cntp-keep_at_p; int ret = 0; if (p+1<=right){ ret += qry(sumst, p+1, right); clear_range(p+1, right); } if (rem){ ret += rem*get_val(p); add_pos(p, -rem); } return ret; } int32_t main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t=1; cin>>t; while (t--){ int n, k; cin>>n>>k; vector a(n+1), b(n+1), c(n+1), d(n+1); vector posa(n+1), posc(n+1), lefta(n+1); vals.clear(); vals.reserve(2*n+1); vals.pb(0); for (int i=1; i<=n; ++i){ cin>>a[i]; vals.pb(a[i]); } for (int i=1; i<=n; ++i)cin>>b[i]; for (int i=1; i<=n; ++i){ cin>>c[i]; vals.pb(c[i]); } for (int i=1; i<=n; ++i)cin>>d[i]; sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); for (int i=1; i<=n; ++i){ posa[i]=get_pos(a[i]); posc[i]=get_pos(c[i]); lefta[i]=upper_bound(vals.begin(), vals.end(), a[i])-vals.begin()+1; } poolptr=0; cntst = build(1, (int)vals.size()); sumst = build(1, (int)vals.size()); add_pos(get_pos(0), k); int ans = 0; for (int i=n; i>=1; --i){ add_pos(posc[i], d[i]); if (d[i]>b[i])remove_smallest(d[i]-b[i]); int left = lefta[i]; if (left<=(int)vals.size()){ int cnt = qry(cntst, left, (int)vals.size()); int take = min(b[i], cnt); if (take){ ans += remove_largest(left, (int)vals.size(), take)-take*a[i]; add_pos(posa[i], take); } } remove_smallest(min(b[i], d[i])); } cout<