#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; vector mem; 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)){ 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(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{ 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{ 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==nullptr?0:l->query(left, right); else if (left>m)return r==nullptr?0:r->query(left, right); else{ int res=0; if (l!=nullptr)res+=l->query(left, m); if (r!=nullptr)res+=r->query(m+1, right); return res; } } }; node* new_node(int s, int e){ node* nd = new node(s, e); mem.pb(nd); return nd; } 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->create(); 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); vals.clear(); 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()); mem.clear(); cntst = new_node(1, (int)vals.size()); sumst = new_node(1, (int)vals.size()); add_pos(get_pos(0), k); int ans = 0; for (int i=n; i>=1; --i){ add_pos(get_pos(c[i]), d[i]); if (d[i]>b[i])remove_smallest(d[i]-b[i]); int left = upper_bound(vals.begin(), vals.end(), a[i])-vals.begin()+1; 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(get_pos(a[i]), take); } } remove_smallest(min(b[i], d[i])); } cout<