#include using namespace std; using ll=long long; using ull=unsigned long long; using P=pair; templateusing minque=priority_queue,greater>; templatebool chmax(T &a,const T &b){return (abool chmin(T &a,const T &b){return (a>b?(a=b,true):false);} templateistream &operator>>(istream &is,pair&p){is>>p.first>>p.second;return is;} templateistream &operator>>(istream &is,tuple&a){is>>std::get<0>(a)>>std::get<1>(a)>>std::get<2>(a);return is;} templateistream &operator>>(istream &is,array&a){for(auto&i:a)is>>i;return is;} templateistream &operator>>(istream &is,vector &a){for(auto &i:a)is>>i;return is;} templatevoid operator++(pair&a,int n){a.first++,a.second++;} templatevoid operator--(pair&a,int n){a.first--,a.second--;} templatevoid operator++(vector&a,int n){for(auto &i:a)i++;} templatevoid operator--(vector&a,int n){for(auto &i:a)i--;} #define overload3(_1,_2,_3,name,...) name #define rep1(i,n) for(int i=0;i<(int)(n);i++) #define rep2(i,l,r) for(int i=(int)(l);i<(int)(r);i++) #define rep(...) overload3(__VA_ARGS__,rep2,rep1)(__VA_ARGS__) #define reps(i,l,r) rep2(i,l,r) #define all(x) x.begin(),x.end() #define pcnt(x) __builtin_popcountll(x) #define fin(x) return cout<<(x)<<'\n',static_cast(0) #define yn(x) cout<<((x)?"Yes\n":"No\n") #define uniq(x) sort(all(x)),x.erase(unique(all(x)),x.end()) template inline int fkey(vector&z,T key){return lower_bound(z.begin(),z.end(),key)-z.begin();} ll myceil(ll a,ll b){return (a+b-1)/b;} template auto vec(const int (&d)[n],const T &init=T()){ if constexpr (id(d,init)); else return init; } #ifdef LOCAL #include #define SWITCH(a,b) (a) #else #define debug(...) static_cast(0) #define debugg(...) static_cast(0) #define SWITCH(a,b) (b) templateostream &operator<<(ostream &os,const pair&p){os<>testcase; for(int i=0;i struct DynamicSegmentTree{ using S=typename M::S; private: struct node{ I key; S v,sum; node *par,*left,*right; node(I key_,S v_):key(key_),v(v_),sum(v_),par(nullptr),left(nullptr),right(nullptr){} inline void update(){ sum=v; if(left)sum=M::op(left->sum,sum); if(right)sum=M::op(sum,right->sum); } void splay(){ while(this->par){ node *p=this->par; if(!this->par->par){ if(p->left==this){ if(this->right)this->right->par=p; p->left=this->right; this->right=p; this->par=nullptr; p->par=this; } else{ if(this->left)this->left->par=p; p->right=this->left; this->left=p; this->par=nullptr; p->par=this; } this->sum=p->sum; p->update(); } else{ node *pp=p->par; if(p->left==this){ if(pp->left==p){ if(this->right)this->right->par=p; if(p->right)p->right->par=pp; p->left=this->right; this->right=p; pp->left=p->right; p->right=pp; if(pp->par){ if(pp->par->left==pp)pp->par->left=this; else pp->par->right=this; } this->par=pp->par; p->par=this; pp->par=p; } else{ if(this->left)this->left->par=pp; if(this->right)this->right->par=p; pp->right=this->left; p->left=this->right; if(pp->par){ if(pp->par->left==pp)pp->par->left=this; else pp->par->right=this; } this->par=pp->par; pp->par=this; p->par=this; this->left=pp; this->right=p; } } else{ if(pp->left==p){ if(this->left)this->left->par=p; if(this->right)this->right->par=pp; p->right=this->left; pp->left=this->right; if(pp->par){ if(pp->par->left==pp)pp->par->left=this; else pp->par->right=this; } this->par=pp->par; p->par=this; pp->par=this; this->left=p; this->right=pp; } else{ if(this->left)this->left->par=p; if(p->left)p->left->par=pp; p->right=this->left; this->left=p; pp->right=p->left; p->left=pp; if(pp->par){ if(pp->par->left==pp)pp->par->left=this; else pp->par->right=this; } this->par=pp->par; p->par=this; pp->par=p; } } this->sum=pp->sum; pp->update(); p->update(); } } } }; bool lower_bound(node*&nd,I key){ while(nd){ if(nd->key==key){ nd->splay(); return true; } else if(nd->key>key){ if(nd->left)nd=nd->left; else{ nd->splay(); return true; } } else{ if(nd->right)nd=nd->right; else{ nd->splay(); if(nd->right){ nd=nd->right; while(nd->left)nd=nd->left; nd->splay(); return true; } return false; } } } return false; } node *root; public: DynamicSegmentTree():root(nullptr){} void set(I key,S val){ if(!root)root=new node(key,val); else{ while(true){ if(root->key==key){ root->splay(); root->v=val; root->update(); break; } else if(root->key>key){ if(root->left)root=root->left; else{ root->splay(); node *nd=new node(key,val); nd->left=root->left; if(nd->left)nd->left->par=nd; nd->right=root; root->par=nd; root->left=nullptr; root->update(); nd->update(); root=nd; break; } } else{ if(root->right)root=root->right; else{ root->splay(); node *nd=new node(key,val); nd->right=root->right; if(nd->right)nd->right->par=nd; nd->left=root; root->par=nd; root->right=nullptr; root->update(); nd->update(); root=nd; break; } } } } } S get(I key){ if(!root)return M::e(); else{ while(true){ if(root->key==key){ root->splay(); return root->v; } else if(root->key>key){ if(root->left)root=root->left; else break; } else{ if(root->right)root=root->right; else break; } } root->splay(); return M::e(); } } S prod(I l,I r){ if(!root)return M::e(); if(!lower_bound(root,l))return M::e(); node *nd=root->left; root->left=nullptr; root->update(); node *pre=root; if(!lower_bound(root,r)){ S ret=root->sum; root=pre; root->splay(); root->left=nd; if(nd)nd->par=root; root->update(); return ret; } S ret=root->left?root->left->sum:M::e(); root=pre; root->splay(); root->left=nd; if(nd)nd->par=root; root->update(); return ret; } S all_prod()const{return root?root->sum:M::e();} }; struct M{ struct S{ int sz; int idx; ll mx; }; static S op(S x,S y){ S res; res.sz=x.sz+y.sz; res.mx=max(x.mx,y.mx); if(res.mx==x.mx)res.idx=x.idx; else res.idx=y.idx; return res; } static S e(){return S{0,-1,-1};} }; void SOLVE(){ int n,m; int k; ll p; cin>>n>>m>>k>>p; vectora(n),c(m); vectorb(n),d(m); cin>>a>>b>>c>>d; b--,d--; vectors(k); cin>>s; vectororda(n); iota(all(orda),0); sort(all(orda),[&](int lhs,int rhs){return b[lhs]ordb(m); iota(all(ordb),0); sort(all(ordb),[&](int lhs,int rhs){return d[lhs]>>cdcol(k); rep(i,m)cdcol[d[i]].emplace_back(c[i],i); rep(i,k)sort(all(cdcol[i])); auto judge=[&](ll x)->tuple { ll res=0; ll mx=-1; int iv=-1,jv=-1; { DynamicSegmentTreeseg; int ptr=0; for(int i:orda){ while(ptrseg; int ptr=0; for(int i:orda){ while(ptrb[i]){ auto now=seg.get(c[ordb[ptr]]); now.sz++; now.mx=c[ordb[ptr]]; now.idx=ordb[ptr]; seg.set(c[ordb[ptr]],now); ptr++; } auto now=seg.prod(-2e9,x-a[i]+1); if(now.sz){ res+=now.sz; if(chmax(mx,now.mx+a[i])){ iv=i; jv=now.idx; } } } } reverse(all(orda)),reverse(all(ordb)); rep(i,n){ int ncol=b[i]; ll ns=s[ncol]; //a[i]+c[i]-ns<=x //c[i]<=x+ns-a[i] auto itr=upper_bound(all(cdcol[ncol]),pair{x+ns-a[i],(int)1e9}); if(itr!=cdcol[ncol].begin()){ res+=itr-cdcol[ncol].begin(); itr--; if(chmax(mx,itr->first+a[i]-ns)){ iv=i; jv=itr->second; } } } return {iv,jv,res}; }; // { // auto [iv,jv,res]=judge(126); // debug(res,iv,jv); // return; // } ll ok=1e10,ng=-1; while(ok-ng>1){ ll mid=(ok+ng)/2; ll cnt=get<2>(judge(mid)); if(cnt>=p)ok=mid; else ng=mid; } auto [ansi,ansj,ans]=judge(ok); debug(ans,ok); cout<