Untitled diff
371 लाइनें
/*
/*
  Compete against Yourself.
  Compete against Yourself.
  Author - Aryan (@aryanc403)
  Author - Aryan (@aryanc403)
*/
*/
/*
/*
  Credits -
  Credits -
  Atcoder library - https://atcoder.github.io/ac-library/production/document_en/ (namespace atcoder)
  Atcoder library - https://atcoder.github.io/ac-library/production/document_en/ (namespace atcoder)
  Github source code of library - https://github.com/atcoder/ac-library/tree/master/atcoder
  Github source code of library - https://github.com/atcoder/ac-library/tree/master/atcoder
  https://codeforces.com/contest/4/submission/150120627
  https://codeforces.com/contest/4/submission/150120627
*/
*/
#include <algorithm>
#include <algorithm>
#include <cassert>
#include <cassert>
#include <functional>
#include <functional>
#include <vector>
#include <vector>
#ifdef _MSC_VER
#ifdef _MSC_VER
#include <intrin.h>
#include <intrin.h>
#endif
#endif
#if __cplusplus >= 202002L
#if __cplusplus >= 202002L
#include <bit>
#include <bit>
#endif
#endif
namespace atcoder {
namespace atcoder {
namespace internal {
namespace internal {
#if __cplusplus >= 202002L
#if __cplusplus >= 202002L
using std::bit_ceil;
using std::bit_ceil;
#else
#else
unsigned int bit_ceil(unsigned int n) {
unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
    return x;
}
}
#endif
#endif
int countr_zero(unsigned int n) {
int countr_zero(unsigned int n) {
#ifdef _MSC_VER
#ifdef _MSC_VER
    unsigned long index;
    unsigned long index;
    _BitScanForward(&index, n);
    _BitScanForward(&index, n);
    return index;
    return index;
#else
#else
    return __builtin_ctz(n);
    return __builtin_ctz(n);
#endif
#endif
}
}
constexpr int countr_zero_constexpr(unsigned int n) {
constexpr int countr_zero_constexpr(unsigned int n) {
    int x = 0;
    int x = 0;
    while (!(n & (1 << x))) x++;
    while (!(n & (1 << x))) x++;
    return x;
    return x;
}
}
}  // namespace internal
}  // namespace internal
}  // namespace atcoder
}  // namespace atcoder
namespace atcoder {
namespace atcoder {
#if __cplusplus >= 201703L
#if __cplusplus >= 201703L
template <class S, auto op, auto e> struct segtree {
template <class S, auto op, auto e> struct segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");
                  "e must work as S()");
#else
#else
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
#endif
#endif
  public:
  public:
    segtree() : segtree(0) {}
    segtree() : segtree(0) {}
    explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
    explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
    explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
    explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)internal::bit_ceil((unsigned int)(_n));
        size = (int)internal::bit_ceil((unsigned int)(_n));
        log = internal::countr_zero((unsigned int)size);
        log = internal::countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
        for (int i = size - 1; i >= 1; i--) {
            update(i);
            update(i);
        }
        }
    }
    }
    void set(int p, S x) {
    void set(int p, S x) {
        assert(0 <= p && p < _n);
        assert(0 <= p && p < _n);
        p += size;
        p += size;
        d[p] = x;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    }
    S get(int p) const {
    S get(int p) const {
        assert(0 <= p && p < _n);
        assert(0 <= p && p < _n);
        return d[p + size];
        return d[p + size];
    }
    }
    S prod(int l, int r) const {
    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= _n);
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        S sml = e(), smr = e();
        l += size;
        l += size;
        r += size;
        r += size;
        while (l < r) {
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            l >>= 1;
            r >>= 1;
            r >>= 1;
        }
        }
        return op(sml, smr);
        return op(sml, smr);
    }
    }
    S all_prod() const { return d[1]; }
    S all_prod() const { return d[1]; }
    template <bool (*f)(S)> int max_right(int l) const {
    template <bool (*f)(S)> int max_right(int l) const {
        return max_right(l, [](S x) { return f(x); });
        return max_right(l, [](S x) { return f(x); });
    }
    }
    template <class F> int max_right(int l, F f) const {
    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l <= _n);
        assert(0 <= l && l <= _n);
        assert(f(e()));
        assert(f(e()));
        if (l == _n) return _n;
        if (l == _n) return _n;
        l += size;
        l += size;
        S sm = e();
        S sm = e();
        do {
        do {
            while (l % 2 == 0) l >>= 1;
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                while (l < size) {
                    l = (2 * l);
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        sm = op(sm, d[l]);
                        l++;
                        l++;
                    }
                    }
                }
                }
                return l - size;
                return l - size;
            }
            }
            sm = op(sm, d[l]);
            sm = op(sm, d[l]);
            l++;
            l++;
        } while ((l & -l) != l);
        } while ((l & -l) != l);
        return _n;
        return _n;
    }
    }
    template <bool (*f)(S)> int min_left(int r) const {
    template <bool (*f)(S)> int min_left(int r) const {
        return min_left(r, [](S x) { return f(x); });
        return min_left(r, [](S x) { return f(x); });
    }
    }
    template <class F> int min_left(int r, F f) const {
    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= _n);
        assert(0 <= r && r <= _n);
        assert(f(e()));
        assert(f(e()));
        if (r == 0) return 0;
        if (r == 0) return 0;
        r += size;
        r += size;
        S sm = e();
        S sm = e();
        do {
        do {
            r--;
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
            if (!f(op(d[r], sm))) {
                while (r < size) {
                while (r < size) {
                    r = (2 * r + 1);
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        sm = op(d[r], sm);
                        r--;
                        r--;
                    }
                    }
                }
                }
                return r + 1 - size;
                return r + 1 - size;
            }
            }
            sm = op(d[r], sm);
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        } while ((r & -r) != r);
        return 0;
        return 0;
    }
    }
  private:
  private:
    int _n, size, log;
    int _n, size, log;
    std::vector<S> d;
    std::vector<S> d;
    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
};
}  // namespace atcoder
}  // namespace atcoder
#ifdef ARYANC403
#ifdef ARYANC403
    #include <header.h>
    #include <header.h>
#else
#else
    #pragma GCC optimize ("Ofast")
    #pragma GCC optimize ("Ofast")
    // #pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
    // #pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
    #pragma GCC target ("sse,sse2,mmx")
    #pragma GCC target ("sse,sse2,mmx")
    #pragma GCC optimize ("-ffloat-store")
    #pragma GCC optimize ("-ffloat-store")
    #include <bits/stdc++.h>
    #include <bits/stdc++.h>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    #define dbg(args...) 42;
    #define dbg(args...) 42;
    #define endl "\n"
    #define endl "\n"
#endif
#endif
// y_combinator from @neal template https://codeforces.com/contest/1553/submission/123849801
// y_combinator from @neal template https://codeforces.com/contest/1553/submission/123849801
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html
template<class Fun> class y_combinator_result {
template<class Fun> class y_combinator_result {
    Fun fun_;
    Fun fun_;
public:
public:
    template<class T> explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {}
    template<class T> explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {}
    template<class ...Args> decltype(auto) operator()(Args &&...args) { return fun_(std::ref(*this), std::forward<Args>(args)...); }
    template<class ...Args> decltype(auto) operator()(Args &&...args) { return fun_(std::ref(*this), std::forward<Args>(args)...); }
};
};
template<class Fun> decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun)); }
template<class Fun> decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun)); }
using namespace std;
using namespace std;
#define fo(i,n)   for(i=0;i<(n);++i)
#define fo(i,n)   for(i=0;i<(n);++i)
#define repA(i,j,n)   for(i=(j);i<=(n);++i)
#define repA(i,j,n)   for(i=(j);i<=(n);++i)
#define repD(i,j,n)   for(i=(j);i>=(n);--i)
#define repD(i,j,n)   for(i=(j);i>=(n);--i)
#define all(x) begin(x), end(x)
#define all(x) begin(x), end(x)
#define sz(x) ((lli)(x).size())
#define sz(x) ((lli)(x).size())
#define eb emplace_back
#define eb emplace_back
#define X first
#define X first
#define Y second
#define Y second
using lli = long long int;
using lli = long long int;
using mytype = long double;
using mytype = long double;
using ii = pair<lli,lli>;
using ii = pair<lli,lli>;
using vii = vector<ii>;
using vii = vector<ii>;
using vi = vector<lli>;
using vi = vector<lli>;
template <class T>
template <class T>
using ordered_set =  __gnu_pbds::tree<T,__gnu_pbds::null_type,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>;
using ordered_set =  __gnu_pbds::tree<T,__gnu_pbds::null_type,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>;
// X.find_by_order(k) return kth element. 0 indexed.
// X.find_by_order(k) return kth element. 0 indexed.
// X.order_of_key(k) returns count of elements strictly less than k.
// X.order_of_key(k) returns count of elements strictly less than k.
// namespace Re = std::ranges;
// namespace Re = std::ranges;
// namespace Ve = std::ranges::views;
// namespace Ve = std::ranges::views;
const auto start_time = std::chrono::high_resolution_clock::now();
const auto start_time = std::chrono::high_resolution_clock::now();
void aryanc403()
void aryanc403()
{
{
auto end_time = std::chrono::high_resolution_clock::now();
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end_time-start_time;
std::chrono::duration<double> diff = end_time-start_time;
    cerr<<"Time Taken : "<<diff.count()<<"\n";
    cerr<<"Time Taken : "<<diff.count()<<"\n";
}
}
const lli INF = 0xFFFFFFFFFFFFFFFLL;
const lli INF = 0xFFFFFFFFFFFFFFFLL;
const lli SEED=chrono::steady_clock::now().time_since_epoch().count();
const lli SEED=chrono::steady_clock::now().time_since_epoch().count();
mt19937_64 rng(SEED);
mt19937_64 rng(SEED);
inline lli rnd(lli l=0,lli r=INF)
inline lli rnd(lli l=0,lli r=INF)
{return uniform_int_distribution<lli>(l,r)(rng);}
{return uniform_int_distribution<lli>(l,r)(rng);}
class CMP
class CMP
{public:
{public:
bool operator()(ii a , ii b) //For min priority_queue .
bool operator()(ii a , ii b) //For min priority_queue .
{    return ! ( a.X < b.X || ( a.X==b.X && a.Y <= b.Y ));   }};
{    return ! ( a.X < b.X || ( a.X==b.X && a.Y <= b.Y ));   }};
void add( map<lli,lli> &m, lli x,lli cnt=1)
void add( map<lli,lli> &m, lli x,lli cnt=1)
{
{
    auto jt=m.find(x);
    auto jt=m.find(x);
    if(jt==m.end())         m.insert({x,cnt});
    if(jt==m.end())         m.insert({x,cnt});
    else                    jt->Y+=cnt;
    else                    jt->Y+=cnt;
}
}
void del( map<lli,lli> &m, lli x,lli cnt=1)
void del( map<lli,lli> &m, lli x,lli cnt=1)
{
{
    auto jt=m.find(x);
    auto jt=m.find(x);
    if(jt->Y<=cnt)            m.erase(jt);
    if(jt->Y<=cnt)            m.erase(jt);
    else                      jt->Y-=cnt;
    else                      jt->Y-=cnt;
}
}
bool cmp(const ii &a,const ii &b)
bool cmp(const ii &a,const ii &b)
{
{
    return a.X<b.X||(a.X==b.X&&a.Y<b.Y);
    return a.X<b.X||(a.X==b.X&&a.Y<b.Y);
}
}
using S = array<lli,3>;
using S = array<lli,3>;
S op(S a, S b) { return S{a[0]+b[0],a[1]+b[1],a[2]+b[2]}; }
S op(S a, S b) { return S{a[0]+b[0],a[1]+b[1],a[2]+b[2]}; }
S e() { return S{0,0,0}; }
S e() { return S{0,0,0}; }
int target;
int target;
bool f(S v) { return v[1]<target; }
bool f(S v) { return v[1]<target; }
int main(void) {
int main(void) {
    ios_base::sync_with_stdio(false);cin.tie(NULL);
    ios_base::sync_with_stdio(false);cin.tie(NULL);
    // freopen("txt.in", "r", stdin);
    // freopen("txt.in", "r", stdin);
    // freopen("txt.out", "w", stdout);
    // freopen("txt.out", "w", stdout);
// cout<<std::fixed<<std::setprecision(35);
// cout<<std::fixed<<std::setprecision(35);
// Ve::iota(1, 6) | Ve::transform([](int x) { return x * 2; }) | Ve::reverse | Ve::take(3)
// Ve::iota(1, 6) | Ve::transform([](int x) { return x * 2; }) | Ve::reverse | Ve::take(3)
lli T=1;
lli T=1;
cin>>T;
cin>>T;
while(T--)
while(T--)
{
{
    lli n,K;
    lli n,K;
    cin>>n>>K;
    cin>>n>>K;
    vii a(n);
    vii a(n);
    for(auto &x:a)
    for(auto &x:a)
        cin>>x.X;
        cin>>x.X;
    for(auto &x:a)
    for(auto &x:a)
        cin>>x.Y;
        cin>>x.Y;
    lli ans = 0;
    lli ans = 0;
    const lli medIdx = (n-2)/2,bigCnt = (n-1)/2+1;
    const lli medIdx = (n-2)/2,bigCnt = (n-1)/2+1;
    vii cr={ii{-INF,-1},ii{INF,0}};
    vii cr={ii{-INF,-1},ii{INF,0}};
    for(lli j=0;j<n;j++)
    for(lli j=0;j<n;j++)
        cr.eb(ii{a[j].X,j});
        cr.eb(ii{a[j].X,j});
    sort(all(cr));
    sort(all(cr));
    const lli M = sz(cr);
    const lli M = sz(cr);
    atcoder::segtree<S, op, e> seg(M);
    atcoder::segtree<S, op, e> seg(M);
    ordered_set<ii> os;
    ordered_set<ii> os;
    auto update=[&](const lli idx,const lli v)->void{
    auto update=[&](const lli idx,const lli v)->void{
        const lli ci = lower_bound(all(cr),ii{a[idx].X,idx})-cr.begin();
        const lli ci = lower_bound(all(cr),ii{a[idx].X,idx})-cr.begin();
        auto g = seg.get(ci);
        auto g = seg.get(ci);
        if(a[idx].Y){
        if(a[idx].Y){
            g[0]+=a[idx].X*v;
            g[0]+=a[idx].X*v;
            g[1]+=v;
            g[1]+=v;
        } else {
        } else {
            g[2]+=v;
            g[2]+=v;
        }
        }
        seg.set(ci,g);
        seg.set(ci,g);
    };
    };
    for(lli i=0;i<n;i++){
    for(lli i=0;i<n;i++){
        os.insert(ii{a[i].X,i});
        os.insert(ii{a[i].X,i});
        update(i,1);
        update(i,1);
    }
    }
    auto chk=[&](const lli K,const lli med)->bool{
    auto chk=[&](const lli K,const lli med)->bool{
        const lli ci = lower_bound(all(cr),ii{med,-2})-cr.begin();
        const lli ci = lower_bound(all(cr),ii{med,-2})-cr.begin();
        const auto pd = seg.prod(ci,M);
        const auto pd = seg.prod(ci,M);
        const lli reqCnt = bigCnt - pd[1]-pd[2];
        const lli reqCnt = bigCnt - pd[1]-pd[2];
        dbg(med,reqCnt);
        dbg(med,reqCnt);
        if(reqCnt<=0)
        if(reqCnt<=0)
            return true;
            return true;
        target=reqCnt+1;
        target=reqCnt+1;
        const lli lr = seg.min_left<f>(ci);
        const lli lr = seg.min_left<f>(ci);
        const auto pd2 = seg.prod(lr,ci);
        const auto pd2 = seg.prod(lr,ci);
        dbg(pd2[1],pd2[0],cr[lr]);
        dbg(pd2[1],pd2[0],cr[lr]);
        if(pd2[1]<reqCnt)
        if(pd2[1]<reqCnt)
            return false;
            return false;
        return pd2[1]*med-pd2[0]<=K;
        return pd2[1]*med-pd2[0]<=K;
    };
    };
    auto getMedian = [&](const lli K)->lli{
    auto getMedian = [&](const lli K)->lli{
        if(K==0)
        if(K==0)
            return os.find_by_order(medIdx)->X;
            return os.find_by_order(medIdx)->X;
        lli l=0,r=INF;
        lli l=0,r=4e9;
        while(r-l>1){
        while(r-l>1){
            const lli mid=(l+r)/2;
            const lli mid=(l+r)/2;
            if(chk(K,mid))
            if(chk(K,mid))
                l=mid;
                l=mid;
            else
            else
                r=mid;
                r=mid;
        }
        }
        dbg(K,l,os);
        dbg(K,l,os);
        return l;
        return l;
    };
    };
    for(lli i=0;i<n;i++){
    for(lli i=0;i<n;i++){
        os.erase(ii{a[i].X,i});
        os.erase(ii{a[i].X,i});
        update(i,-1);
        update(i,-1);
        if(a[i].Y==0)
        if(a[i].Y==0)
            ans=max(ans,a[i].X+getMedian(K));
            ans=max(ans,a[i].X+getMedian(K));
        else
        else
            ans=max(ans,a[i].X+K+getMedian(0));
            ans=max(ans,a[i].X+K+getMedian(0));
        os.insert(ii{a[i].X,i});
        os.insert(ii{a[i].X,i});
        update(i,1);
        update(i,1);
    }
    }
    cout<<ans<<endl;
    cout<<ans<<endl;
}   aryanc403();
}   aryanc403();
    return 0;
    return 0;
}
}