Comparing sensitive data, confidential files or internal emails?

Most legal and privacy policies prohibit uploading sensitive data online. Diffchecker Desktop ensures your confidential information never leaves your computer. Work offline and compare documents securely.

Untitled diff

Created Diff never expires
1 removal
371 lines
1 addition
371 lines
/*
/*
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;
}
}