Untitled diff
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;
}
}