Problem:
財宝 (Treasures)
問題
盗賊の Anna と Bruno は大富豪の邸宅に忍び込み，財宝 1 から財宝 N までの N 個の財宝を見つけた．これらの財宝を Anna と Bruno で分配することになった．財宝のうちのいくつかを Anna が取り，残りの財宝のうちのいくつかを Bruno が取る．同じ財宝を 2 人が取ることはできない．Anna や Bruno は財宝を 1 個も取らなくてもよい．また，残った財宝は邸宅に残しておくので，2 人とも取らない財宝があってもよい．
それぞれの財宝には「市場価値」と「貴重度」という 2 つの値が定まっている．Anna が取った財宝の市場価値の合計と Bruno が取った財宝の市場価値の合計の差の絶対値が D 以下なら，Anna は公平だと思って満足する．一方，Bruno は，Anna より貴重度の大きい財宝が欲しいと思っている．
Anna が満足するように財宝を分配したときの，Bruno が取った財宝の貴重度の合計から Anna が取った財宝の貴重度の合計を引いた値の最大値を求めよ．
入力
入力は 1 + N 行からなる．
1 行目には，2 つの整数 N, D (1 ≤ N ≤ 30，0 ≤ D ≤ 10
15
) が空白を区切りとして書かれている．これは，財宝の個数が N 個であり，Anna が取った財宝の市場価値の合計と Bruno が取った財宝の市場価値の合計の差の絶対値が D 以下なら Anna が満足することを表す．
続く N 行のうちの i 行目 (1 ≤ i ≤ N) には，2 つの整数 X
i
, Y
i
(0 ≤ X
i
≤ 10
15
，0 ≤ Y
i
≤ 10
15
) が空白を区切りとして書かれている．これは，財宝 i の市場価値が X
i
であり，貴重度が Y
i
であることを表す．
与えられる 5 つの入力データのうち，入力 1 では N ≦ 10 を満たす．また，入力 2 では D = 0 を満たす．
出力
Anna が満足するように財宝を分配したときの，Bruno が取った財宝の貴重度の合計から Anna が取った財宝の貴重度の合計を引いた値の最大値を 1 行で出力せよ．
入出力例
入力例 1
6 15
50 900
30 200
40 100
80 600
60 100
70 700
出力例 1
1200
入力例 2
5 0
0 1000000000000000
0 1000000000000000
1 1
1000000000000000 0
1000000000000000 0
出力例 2
2000000000000000
入出力例 1 においては，Anna が財宝 2 と財宝 3 と財宝 5 を取り，Bruno が財宝 1 と財宝 6 を取ると，取った財宝の市場価値の合計は Anna が 130，Bruno が 120 となり，差の絶対値 10 が D = 15 以下なので Anna は満足する．このとき，取った財宝の貴重度の合計は Anna が 400，Bruno が 1600 となり，Bruno が取った財宝の貴重度の合計から Anna が取った財宝の貴重度の合計を引いた値は 1200 となる．これが最大である．
問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: #include <iostream>
#include <algorithm>
#include <deque>
#include <functional>
using namespace std;
long long n, d, a[39], b[39], mid; int power[39]; pair<long long, long long>A[15000000], B[15000000];
int main() {
	cin >> n >> d; mid = n / 2;
	for (int i = 0; i < n; i++)cin >> a[i] >> b[i];
	power[0] = 1; for (int i = 1; i < 39; i++)power[i] = power[i - 1] * 3;
	for (int i = 0; i < power[mid]; i++) {
		long long X1 = 0, X2 = 0;
		for (int j = 0; j < mid; j++) {
			int C = (i / power[j]) % 3;
			if (C == 0) { X1 += a[j]; X2 += b[j]; }
			if (C == 1) { X1 -= a[j]; X2 -= b[j]; }
		}
		A[i] = make_pair(X1, X2);
	}
	for (int i = 0; i < power[n - mid]; i++) {
		long long X1 = 0, X2 = 0;
		for (int j = 0; j < n - mid; j++) {
			int C = (i / power[j]) % 3;
			if (C == 0) { X1 += a[mid + j]; X2 += b[mid + j]; }
			if (C == 1) { X1 -= a[mid + j]; X2 -= b[mid + j]; }
		}
		B[i] = make_pair(X1, X2);
	}
	sort(A, A + power[mid], greater<pair<long long, long long>>());
	sort(B, B + power[n - mid]); deque<pair<long long, long long>>Q;
	int L = 0, R = 0; long long minx = 0;
	for (int i = 0; i < power[mid]; i++) {
		int pos1 = lower_bound(B, B + power[n - mid], make_pair(-A[i].first - d, -(1LL << 62))) - B;
		int pos2 = lower_bound(B, B + power[n - mid], make_pair(-A[i].first + d, (1LL << 62))) - B;
		for (int i = R; i < pos2; i++) {
			while (!Q.empty() && B[i].second <= Q.back().first)Q.pop_back();
			Q.push_back(make_pair(B[i].second, i));
		}
		while (L < pos1) { if (Q.front().second == L)Q.pop_front(); L++; }
		R = pos2; if (!Q.empty()) minx = min(minx, Q.front().first + A[i].second);
	}
	cout << -minx << endl;
	return 0;
}
accuracy: 1
time_ms: 5970
memory_kb: 453928
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;

#include<atcoder/modint>
using namespace atcoder;
using mint=modint998244353;

using ll =long long;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ll N,D;
    cin>>N>>D;
    vector<array<ll,2>> P(N);
    for(int i=0;i<N;i++)cin>>P[i][0]>>P[i][1];
    
    vector<array<ll,2>> MV,MB;
    ll H=N/2;
    ll B=N-H;
    for(int bit=0;bit<(1<<H);bit++){
        for (ll b = bit; b >= 0; b = (b - 1) & bit) {
            ll S=0,U=0;
            for(int i=0;i<H;i++){
                if(bit&(1<<i)){
                    if(b&(1<<i)){
                        S+=P[i][0];
                        U-=P[i][1];
                    }
                    else{
                        S-=P[i][0];
                        U+=P[i][1];
                    }
                }
            }
            MV.push_back({S+ll(1e17),U});
            if (b == 0)break;
        }
    }
    sort(MV.begin(),MV.end());
    
    ll an=0;


    for(int bit=0;bit<(1<<B);bit++){
        for (ll b = bit; b >= 0; b = (b - 1) & bit) {
            ll S=0,U=0;
            for(int i=0;i<B;i++){
                if(bit&(1<<i)){
                    if(b&(1<<i)){
                        S-=P[i+H][0];
                        U-=P[i+H][1];
                    }
                    else{
                        S+=P[i+H][0];
                        U+=P[i+H][1];
                    }
                }
            }
            MB.push_back({S+ll(1e17),U});
            if (b == 0)break;
        }
    }
    sort(MB.begin(),MB.end());
    deque<array<ll,2>> DEQ;
    ll R=0;
    for(int i=0;i<MB.size();i++){
        while(R<MV.size()&&MV[R][0]<=MB[i][0]+D){
            while(DEQ.size()>0&&DEQ.back()[0]<=MV[R][1])DEQ.pop_back();
            DEQ.push_back({MV[R][1],MV[R][0]});
            R++;
        }
        while(DEQ.size()>0&&DEQ.front()[1]<MB[i][0]-D)DEQ.pop_front();
        if(DEQ.size()>0)an=max(an,MB[i][1]+DEQ.front()[0]);
    }
    cout<<an<<endl;
}
accuracy: 1
time_ms: 3280
memory_kb: 491060
final_rank: 11

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define HUGE_NUM 999999999999999999

enum Type{
	One,
	Two,
};

enum Which{
	A,
	B,
	Skip,
};

struct Data{
	ll market_value,precious_degree;
};

struct Info{
	Info(ll arg_market_value_diff,ll arg_precious_degree_diff){
		market_value_diff = arg_market_value_diff;
		precious_degree_diff = arg_precious_degree_diff;
	}
	bool operator<(const struct Info &arg) const{ //市場価値の差の降順
		return market_value_diff > arg.market_value_diff;
	}
	bool operator==(const struct Info &arg) const{
		return market_value_diff == arg.market_value_diff
				&&precious_degree_diff == arg.precious_degree_diff;
	}

	ll market_value_diff,precious_degree_diff;
};

ll N,DIFF;
Data data[30];
int start_index[2],end_index[2];
vector<Info> V[2];
ll* table;
int SIZE = 1;

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(SIZE < first_N)SIZE *= 2;
}

void update(int loc,ll value){
	loc += SIZE-1;

	table[loc] = value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		table[parent] = max(table[2*parent+1],table[2*parent+2]); //親は左右の子の大きい方の値を持つ

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}


ll query(int search_left,int search_right,int node_id,int node_left,int node_right){

	if(search_right < node_left || search_left > node_right)return -HUGE_NUM;

	if(search_left <= node_left && search_right >= node_right){
		return table[node_id];
	}

	ll left_max = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
	ll right_max = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

	return max(left_max,right_max);
}


bool rangeCheck(ll value){
	if(value >= -DIFF && value <= DIFF){
		return true;
	}else{
		return false;
	}
}

void make_group(Which array[30],int index,Type type){
	if(index == end_index[type]+1){

		ll A_market = 0,A_precious = 0,B_market = 0,B_precious = 0;
		for(int i = start_index[type]; i <= end_index[type]; i++){
			if(array[i] == Skip)continue;

			if(array[i] == A){
				A_market += data[i].market_value;
				A_precious += data[i].precious_degree;
			}else{
				B_market += data[i].market_value;
				B_precious += data[i].precious_degree;
			}
		}

		V[type].push_back(Info(B_market-A_market,B_precious-A_precious));
		return;
	}

	Which next_array[3][30];
	for(int i = 0; i < 3; i++){
		for(int k = start_index[type]; k < index; k++){
			next_array[i][k] = array[k];
		}
	}

	next_array[0][index] = A;
	next_array[1][index] = B;
	next_array[2][index] = Skip;

	for(int i = 0; i < 3; i++){
		make_group(next_array[i],index+1,type);
	}
}

int main(){

	scanf("%lld %lld",&N,&DIFF);

	for(int i = 0; i < N; i++){
		scanf("%lld %lld",&data[i].market_value,&data[i].precious_degree);
	}

	if(N == 1){
		if(data[0].market_value <= DIFF){
			printf("%lld\n",data[0].precious_degree);
		}else{
			printf("0\n");
		}
		return 0;
	}

	V[One].push_back(Info(0,0));
	V[Two].push_back(Info(0,0));

	//0～N-1の財宝を2つに分割する
	start_index[One] = 0;
	end_index[One] = (N-1)/2;

	start_index[Two] = end_index[One]+1;
	end_index[Two] = N-1;


	Which first_array[30];

	make_group(first_array,start_index[One],One);
	make_group(first_array,start_index[Two],Two);

	sort(V[One].begin(),V[One].end()); //Oneは降順に
	V[One].erase(unique(V[One].begin(),V[One].end()),V[One].end());

	sort(V[Two].begin(),V[Two].end());
	V[Two].erase(unique(V[Two].begin(),V[Two].end()),V[Two].end());
	reverse(V[Two].begin(),V[Two].end()); //Twoは昇順に

	ll ans = -HUGE_NUM;

	int left,right,start_index = 0;
	int calc_left,calc_right,m;
	int One_num = (int)V[One].size(),Two_num = (int)V[Two].size();

	//2分探索で、range制約を満たす左端と右端を求める
	while(start_index < One_num){

		left = BIG_NUM; //左端を求める
		calc_left = 0, calc_right = Two_num-1,m = (calc_left+calc_right);
		while(calc_left<=calc_right){
			if(V[One][start_index].market_value_diff+V[Two][m].market_value_diff >= -DIFF){
				left = m;
				calc_right = m-1; //より左へ

			}else{
				calc_left = m+1;
			}
			m = (calc_left+calc_right)/2;
		}

		if(left == BIG_NUM){
			start_index++;
			continue;
		}

		right = BIG_NUM; //右端を求める
		calc_left = 0, calc_right = Two_num-1,m = (calc_left+calc_right);
		while(calc_left<=calc_right){
			if(V[One][start_index].market_value_diff+V[Two][m].market_value_diff <= DIFF){
				right = m;
				calc_left = m+1; //より右へ

			}else{
				calc_right = m-1;
			}
			m = (calc_left+calc_right)/2;
		}
		if(right == BIG_NUM || left > right){
			start_index++;
			continue;
		}
		break;
	}

	if(start_index == One_num){
		printf("0\n");
		return 0;
	}

	init(Two_num);
	table = new ll[2*SIZE-1];

	for(int i = 0; i <= 2*SIZE-2; i++)table[i] = -HUGE_NUM;
	for(int i = 0; i < Two_num; i++)update(i,V[Two][i].precious_degree_diff);

	ans = V[One][start_index].precious_degree_diff+query(left,right,0,0,SIZE-1);

	for(int i = start_index+1; i < One_num; i++){
		while(left < Two_num && V[One][i].market_value_diff+V[Two][left].market_value_diff < -DIFF)left++;
		if(left == Two_num)break;
		while(right < Two_num && V[One][i].market_value_diff+V[Two][right].market_value_diff <= DIFF)right++;
		right--;

		if(left > right)continue;

		ans = max(ans,V[One][i].precious_degree_diff+query(left,right,0,0,SIZE-1));
	}

	if(ans == -HUGE_NUM){
		printf("0\n");
	}else{
		printf("%lld\n",ans);
	}

	return 0;
}
accuracy: 1
time_ms: 4230
memory_kb: 716696
final_rank: 18

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 2 "cp-library/src/data_structure/sliding_window_aggregation.hpp"

template < class monoid >
struct swag_queue {
  public:
    using T = typename monoid::set;
    class node {
      public:
        T value, sum;
        node() : value(monoid::id()), sum(monoid::id()) {}
        node(const T& value, const T& sum) : value(value), sum(sum) {}
    };
    std::stack<node> front_stack, back_stack;

  public:
    swag_queue() { front_stack.push(node()), back_stack.push(node()); }
    int size() const {
        return (int(front_stack.size()) - 1) + (int(back_stack.size()) - 1);
    }
    bool empty() const {
        return size() == 0;
    }
    T fold() const {
        return monoid::op(front_stack.top().sum, back_stack.top().sum);
    }
    void push(const T& x) {
        back_stack.push(node(x, monoid::op(back_stack.top().sum, x)));
    }
    void pop() {
        assert(not empty());
        if(front_stack.size() == 1) {
            while(back_stack.size() > 1) {
                front_stack.push(node(back_stack.top().value, monoid::op(back_stack.top().value, front_stack.top().sum)));
                back_stack.pop();
            }
        }
        front_stack.pop();
    }
};

template < class monoid >
struct swag_deque {
  private:
    using T = typename monoid::set;
    class node {
      public:
        T value, sum;
        node() : value(monoid::id()), sum(monoid::id()) {}
        node(const T& value, const T& sum) : value(value), sum(sum) {}
    };
    std::stack<node> front_stack, back_stack;

  public:
    swag_deque() { front_stack.push(node()), back_stack.push(node()); }
    int size() const { return (int(front_stack.size()) - 1) + (int(back_stack.size()) - 1); }
    bool empty() const { return size() == 0; }

    T fold() const { return monoid::op(front_stack.top().sum, back_stack.top().sum); }
    void push_front(const T& x) { push(front_stack, x, 1); }
    void push_back (const T& x) { push( back_stack, x, 0); }
    void pop_front() { assert(not empty()); if(front_stack.size() == 1) amortize( back_stack, front_stack, 1); front_stack.pop(); }
    void pop_back () { assert(not empty()); if( back_stack.size() == 1) amortize(front_stack,  back_stack, 0);  back_stack.pop(); }

  private:
    void push(std::stack<node>& st, const T& x, int f) {
        st.push(node(x, f ? monoid::op(x, st.top().sum) : monoid::op(st.top().sum, x)));
    }
    void amortize(std::stack<node>& from, std::stack<node>& to, int f) {
        std::stack< T > st;
        while(st.size() < from.size() - 2) st.push(from.top().value), from.pop();
        while(from.size() > 1) push(to, from.top().value, f), from.pop();
        while(not st.empty()) push(from, st.top(), 1 - f), st.pop();
        printer::flush();
    }
};
#line 3 "cp-library/src/algebra/minmax.hpp"

template < class T > class min_monoid {
  public:
    using set = T;
    static constexpr T op(const T &l, const T &r) { return std::min(l, r); }
    static constexpr T id() { return std::numeric_limits< T >::max(); }
    static constexpr bool comm = true;
};

template < class T > class max_monoid {
  public:
    using set = T;
    static constexpr T op(const T &l, const T &r) { return std::max(l, r); }
    static constexpr T id() { return std::numeric_limits< T >::min(); }
    static constexpr bool comm = true;
};
#line 5 "A.cpp"

int main() {
    int N = in(); i64 D = in();
    vector<i64> X(N), Y(N);
    for(int i : rep(N)) X[i] = in(), Y[i] = in();

    const int N1 = N / 2;
    const int N2 = N - N1;

    vector<pair<i64,i64>> A = [&] {
        vector<pair<i64,i64>> res;
        for(int S : rep(1 << N1)) {
            for(int T = S; ; T = (T - 1) & S) {
                i64 a = 0, b = 0;
                for(int i : rep(N1)) {
                    if(S & (1 << i)) {
                        if(T & (1 << i)) {
                            a += X[i];
                            b += Y[i];
                        } else {
                            a -= X[i];
                            b -= Y[i];
                        }
                    } else {

                    }
                }
                res.push_back({a, b});
                if(T == 0) break;
            }
        }
        sort(res);
        return res;
    }();

    vector<pair<i64,i64>> B = [&] {
        vector<pair<i64,i64>> res;
        for(int S : rep(1 << N2)) {
            for(int T = S; ; T = (T - 1) & S) {
                i64 a = 0, b = 0;
                for(int i : rep(N2)) {
                    if(S & (1 << i)) {
                        if(T & (1 << i)) {
                            a += X[N1 + i];
                            b += Y[N1 + i];
                        } else {
                            a -= X[N1 + i];
                            b -= Y[N1 + i];;
                        }
                    } else {

                    }
                }
                res.push_back({a, b});

                if(T == 0) break;
            }
        }
        sort(res);
        return res;
    }();

    swag_queue<max_monoid<i64>> q;
    const int nA = A.size();
    const int nB = B.size();
    int L = 0, R = 0;
    i64 ans = 0;

    for(int i : rep(nA)) {
        while(R < nB and B[R].first <= A[i].first + D) {
            q.push(B[R].second);
            R++;
        }
        while(L < nB and not(A[i].first - D <= B[L].first)) {
            q.pop();
            L++;
        }
        if(not q.empty() and A[i].first - D <= B[L].first and B[R - 1].first <= A[i].first + D) {
            chmax(ans, q.fold() - A[i].second);
        }
    }
    print(ans);
}
accuracy: 1
time_ms: 3180
memory_kb: 491828
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    ll D; cin >> D;
    vector<ll> x(n),y(n);
    for (int i = 0; i < n; ++i) {
        cin >> x[i] >> y[i];
    }
    vector<int> po(20); po[0] = 1;
    for (int i = 1; i < 20; ++i) {
        po[i] = po[i-1] * 3;
    }
    vector<pair<ll,ll>> a,b;
    {
        int pn = n/2;
        int bn = n-pn;
        a.resize(po[pn]);
        b.resize(po[bn]);
        auto dfs = [&](auto dfs, int l, int r, int i, pair<ll,ll> cur, vector<pair<ll,ll>> &v, int &pos) -> void {
            if (i == r) {
                v[pos++] = cur;
                return;
            }
            dfs(dfs, l, r, i+1, cur, v, pos);
            dfs(dfs, l, r, i+1, {cur.first+x[i], cur.second+y[i]}, v, pos);
            dfs(dfs, l, r, i+1, {cur.first-x[i], cur.second-y[i]}, v, pos);
        };
        int pos = 0;
        dfs(dfs, 0, pn, 0, {0,0}, a, pos);
        pos = 0;
        dfs(dfs, pn, n, pn, {0,0}, b, pos);
    }
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());
    sort(b.begin(), b.end());
    b.erase(unique(b.begin(), b.end()), b.end());

    ll res = 0;
    deque<pair<ll,ll>> dq;
    int id = b.size()-1;
    for (int i = 0; i < a.size(); ++i) {
        ll d = a[i].first;
        while (id >= 0 and d+b[id].first >= -D) {
            if (d+b[id].first <= D) {
                while (dq.size() and dq.back().second <= b[id].second) dq.pop_back();
                dq.push_back(b[id]);
            }
            id -= 1;
        }
        while (dq.size() and dq.front().first+d > D) dq.pop_front();
        if (dq.size()) res = max(res, a[i].second+dq.front().second);
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 2420
memory_kb: 451600
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
#include <cmath>
using namespace std;
long long int st[21523360];
long long int minn=-4*pow(10,17);
struct E{
	long long int x,y;
	bool operator<(const E& e)const{
		if(x!=e.x)return x<e.x;
		return y<e.y;
	}
};
vector<E> vsl,vsr,vst;
long long int xs[31];
long long int ys[31];
long long int n,d;
void f(long long int x,long long int y,int deep1,int r,vector<E>& vs){
	if(deep1==r){
		E e;
		e.x=x;
		e.y=y;
		vs.push_back(e);
	}else{
		f(x+xs[deep1],y-ys[deep1],deep1+1,r,vs);
		f(x-xs[deep1],y+ys[deep1],deep1+1,r,vs);
		f(x,y,deep1+1,r,vs);
	}
}
long long int addst(int no,int x,long long int v,int l,int r){
	if(x<l || r<x)return st[no];
	if(l==r){
		st[no]=v;
		return v;
	}else{
		int d=(r-l+1)/3;
		int m1=l+d;
		int m2=m1+d;
		long long int res=addst(no*3+1,x,v,l,m1-1);
		res=max(res,addst(no*3+2,x,v,m1,m2-1));
		res=max(res,addst(no*3+3,x,v,m2,r));
		st[no]=max(res,st[no]);
		return st[no];
	}
}
long long int getst(int no,int l,int r,int l2,int r2){
	if(r2<l || r<l2)return minn;
	if(l==r){
		return st[no];
	}else if(l2<=l && r<=r2){
		//cout<<l<<" "<<r<<" st "<<st[no]<<endl;
		return st[no];
	}else{
		int d=(r-l+1)/3;
		int m1=l+d;
		int m2=m1+d;
		long long int res=getst(no*3+1,l,m1-1,l2,r2);
		res=max(res,getst(no*3+2,m1,m2-1,l2,r2));
		res=max(res,getst(no*3+3,m2,r,l2,r2));
		return res;
	}
	
}

int main() {
	for(int i=0;i<21523360;i++){
		st[i]=minn;
	}
	cin>>n>>d;
	
	for(int i=0;i<n;i++){
		cin>>xs[i]>>ys[i];
	}
	long long int ans=0;
	if(n==1){
		if(xs[0]<=d){
			cout<<ys[0]<<endl;
		}else{
			cout<<0<<endl;
		}
	}else{
		f(0,0,0,n/2,vsl);
		f(0,0,n/2,n,vsr);
		sort(vsl.begin(),vsl.end());
		sort(vsr.begin(),vsr.end());
		int maxr=vsr.size()-1;
		for(int i=0;i<vsr.size();i++){
			long long int t=addst(0,i,vsr[i].y,0,maxr);
		}
		int pd=maxr;
		int pu=maxr;
		
		int maxl=vsl.size();
		for(int i=0;i<maxl;i++){	
			long long int x=vsl[i].x;
			while(pd>0 && x+vsr[pd-1].x>=-d){
				pd--;
			}
			
			while(pu>0 && vsr[pu-1].x+x>d){
				pu--;
			}
			if(pu>pd && vsr[pu].x+x>d)pu--;
			long long int x1,x2;
			x1=vsr[pu].x;
			x2=vsr[pd].x;
			//cout<<x<<" "<<x1<<" "<<x2<<endl;
			if(abs(x+x1)<=d && abs(x+x2)<=d){
				
				long long int t2=getst(0,0,maxr,pd,pu);
				//cout<<vsl[i].y<<" "<<t2<<endl;
				ans=max(ans,vsl[i].y+t2);
			}
		}
		cout<<ans<<endl;
	}
	
	//f(0,0,0,n,vst);
	//long long int ans2=0;
	//for(int i=0;i<vst.size();i++){
	//	E e1=vst[i];
//		if(abs(e1.x)<=d)ans2=max(ans2,e1.y);
//	}
//	cout<<ans2<<endl;
	return 0;
}
accuracy: 1
time_ms: 3680
memory_kb: 659972
final_rank: 16

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/modint>

#define rep(i, x) for (ll i = 0; i < x; i++)
#define rep2(i, x) for (ll i = 1; i <= x; i++)
#define rep3(i, x, y) for (ll i = x; i < y; i++)
#define REP(i, x) for (ll i = x - 1; i >= 0; i--)
#define REP2(i, x) for (ll i = x; i >= 1; i--)
#define mpa make_pair
#define mpt make_tuple
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define puts(x) cout << (x) << "\n"
using ll = long long;
using ld = long double;
using namespace std;
// using namespace atcoder;

const ll INF = 1000000000000000000;
const int intINF = 1000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = acos(-1);
// const ld EPS = 1e-9;
typedef string::const_iterator State;
class ParseError
{
};

template <typename T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}
template <typename T>
bool chmin(T &a, const T &b)
{
    if (a > b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}

bool isprime(ll p)
{
    if (p == 1)
        return false;
    for (ll i = 2; i * i <= p; i++)
    {
        if (p % i == 0)
            return false;
    }
    return true;
}
//エラトステネスの篩
vector<bool> isprime_format(ll n)
{
    vector<bool> P(n + 1, 1);
    P[0] = P[1] = 1;
    for (ll i = 2; i * i <= n; i++)
    {
        if (!P[i])
            continue;
        for (int j = i + i; j <= n; j += i)
            P[j] = false;
    }
    return P;
}
vector<ll> prime_format(ll n)
{
    vector<bool> P = isprime_format(n);
    vector<ll> ans;
    for (int i = 2; i <= n; i++)
    {
        if (P[i])
            ans.push_back(i);
    }
    return ans;
}
ll extGCD(ll a, ll b, ll &x, ll &y)
{
    // ax + by = cが整数解をもつための必要十分条件は c が gcd(a,b) で割り切れること。
    //  返り値: a と b の最大公約数
    //  ax + by = gcd(a, b) を満たす (x, y) が格納される
    // main関数内に extGCD(a, b, x, y); でx, yに解が格納
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
ll keta(ll n)
{
    ll res = 0;
    while (n >= 1)
    {
        // res++;
        res += n % 10;

        n /= 10;
    }
    return res;
}
ll modpow(ll x, ll y, ll m)
{
    ll res = 1;
    while (y)
    {
        if (y % 2)
        {
            res *= x;
            res %= m;
        }
        x = x * x % m;
        y /= 2;
    }
    return res;
}

unsigned int xorshift()
{
    // xorshift　from 「ビット演算 (bit 演算) の使い方を総特集！ 」
    // 1~6まで出したいときは
    // xorshift() % 6 + 1
    static unsigned int tx = 123456789, ty = 362436069, tz = 521288629, tw = 88675123;
    unsigned int tt = (tx ^ (tx << 11));
    tx = ty;
    ty = tz;
    tz = tw;
    return (tw = (tw ^ (tw >> 19)) ^ (tt ^ (tt >> 8)));
}
uint64_t seed = 123456789;
uint64_t xorshift64()
{
    seed ^= seed << 13;
    seed ^= seed >> 17;
    seed ^= seed << 7;
    return seed;
}
int rand_int(int l, int r)
{
    return l + int(xorshift64() % (r - l));
}
double randouble()
{
    return double(xorshift64()) / double(uint64_t(-1));
}

typedef pair<ll, ll> P;
typedef pair<ll, P> pp;
//左上右下
ll dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
ll ndx[4] = {1, -1, -1, 1}, ndy[4] = {1, 1, -1, -1};
char ds[4] = {'l', 'u', 'r', 'd'};
char dl[4] = {'L', 'U', 'R', 'D'};

vector<ll> spf;
void smallest_prime_factors(ll n)
{
    spf.resize(n + 1);
    spf[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (!spf[i])
        {
            for (int j = i; j < n; j += i)
            {
                spf[j] = i;
            }
        }
    }
}
std::map<int, int> high_speed_prime_factor(int n)
{
    std::map<int, int> res;
    while (n != 1)
    {
        res[spf[n]]++;
        n /= spf[n];
    }
    return res;
}

////////////////////////////////struct

struct Comb
{
    // https://atcoder.jp/contests/abc156/submissions/33741990

    ll nCrMAX;
    ll m;
    vector<ll> fac, finv, inv; // n!、1/n!、1/n

    Comb(ll kMOD, ll kMAX = 612345)
    {
        nCrMAX = kMAX;
        m = kMOD;
        fac.resize(nCrMAX);
        finv.resize(nCrMAX);
        inv.resize(nCrMAX);

        fac[0] = fac[1] = 1;
        finv[0] = finv[1] = 1;
        inv[1] = 1;
        for (int i = 2; i < nCrMAX; i++)
        {
            fac[i] = fac[i - 1] * i % m;
            inv[i] = m - inv[m % i] * (m / i) % m;
            finv[i] = finv[i - 1] * inv[i] % m;
        }
    }

    ll nCr(ll n, ll k)
    {
        if (k < nCrMAX)
        {
            ll res = 1;
            for (int i = n - k + 1; i <= n; i++)
            {
                res *= i;
                res %= m;
            }
            res = res * finv[k] % m;
            return res;
        }
        else
        {
            if (n < k)
                return 0;
            if (n < 0 || k < 0)
                return 0;
            return fac[n] * (finv[k] * finv[n - k] % m) % m;
        }
    }

    ll nCr1(ll n, ll k)
    {
        if (n < k)
            return 0;
        if (n < 0 || k < 0)
            return 0;
        return fac[n] * (finv[k] * finv[n - k] % m) % m;
    }

    //(nが大きくて)kが小さい時
    // nCrMAXはk+2まででOK
    ll nCr2(ll n, ll k)
    {
        ll res = 1;
        for (int i = n - k + 1; i <= n; i++)
        {
            res *= i;
            res %= m;
        }
        res = res * finv[k] % m;
        return res;
    }
};

void yes(bool a) { cout << (a ? "yes" : "no") << endl; }
void YES(bool a) { cout << (a ? "YES" : "NO") << endl; }
void Yes(bool a) { cout << (a ? "Yes" : "No") << endl; }
void Possible(bool a) { cout << (a ? "Possible" : "Impossible") << endl; }
// struct edge {
//	ll to; ll cost;
// };

struct Point
{
    ll x, y;
    Point operator+(const Point &p) const noexcept { return {x + p.x, y + p.y}; }
    Point operator-(const Point &p) const noexcept { return {x - p.x, y - p.y}; }
    Point operator*(const ll k) const noexcept { return {x * k, y * k}; }
    Point operator/(const ll k) const noexcept { return {x / k, y / k}; }
    Point &operator+=(const Point &p) noexcept
    {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator-=(const Point &p) noexcept
    {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    bool operator<(const Point &p) const noexcept { return (x != p.x ? x < p.x : y < p.y); }
};

// using mint = modint998244353;

struct edge
{
    ll to, cost;
};

struct status
{
    ll d1;
    ll d2;

    // bool operator<(const status& rhs) const { return c < rhs.c; };
    // bool operator>(const status& rhs) const { return c > rhs.c; };
    bool operator<(const status &rhs) const { return d1 < rhs.d1; };
    bool operator>(const status &rhs) const { return d1 > rhs.d1; };
};
struct rmq2
{
    ll nn;
    vector<ll> dat;

    rmq2(ll n = 1)
    {
        init(n);
    }
    void init(ll n_)
    { //初期化
        nn = n_;
        dat.resize(nn + nn / 2);
    }
    void update(ll k, ll a)
    { // k番目の値(0-indexed)をaに変更
        k += nn / 2;
        dat[k] = a; //葉の節点
        while (k > 0)
        { //登りながら更新
            k = (k - 1) / 3;
            dat[k] = max({dat[k * 3 + 1], dat[k * 3 + 2], dat[k * 3 + 3]});
        }
    }
    //[a, b)の最大値を求める
    // kは節点の番号、l, rはその節点が[l, r)に対応づいていることを表す。
    //したがって外からはquery(a, b, 0, 0, nn)として呼ぶ。
    ll query(ll a, ll b, ll k, ll l, ll r)
    {
          //cout<<a<<' '<<b<<' '<<l << ' ' << r<<endl;
        //[a, b)と[l, r)が交差しなければ、0
        //[a, b)が[l, r)を完全に含んでいれば、この節点の値
        if (r <= a || b <= l)
        {
            return 0;
        }
        if (a <= l && r <= b)
        {
            return dat[k];
        }
        else
        {
            ll v1 = query(a, b, k * 3 + 1, l, (l + l+ r) / 3);
            ll v2 = query(a, b, k * 3 + 2, (l + l + r) / 3, (l + r + r) / 3);
            ll v3 = query(a, b, k * 3 + 3, (l + r + r) / 3, r);
            return max({v1, v2, v3});
        }
    }
};

int main()
{
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    // cout << fixed << setprecision(15);
    // priority_queue<ll, vector<ll>, greater<ll>> que;
    // priority_queue<P, vector<P>, greater<P>> que;
    // priority_queue<status, vector<status>, greater<status>> que;

    // 15個ずつに分けて3^15した後に、sortして、尺取りしながらセグメント木。
    // MLEしたのでセグメント木を3の倍数に変えた

    ll n, d;
    cin >> n >> d;

    vector<int> three(17);
    int kt = 1;
    rep(i, 17)
    {
        three[i] = kt;
        kt *= 3;
    }

    vector<Point> in(n);
    rep(i, n)
    {
        cin >> in[i].x >> in[i].y;
    }

    // 前半 N/2 個
    int ko1 = three[n / 2];
    vector<status> f(ko1);
    for (int i = 0; i < ko1; i++)
    {
        for (int j = 0; j < (n / 2); j++)
        {
            if ((i / three[j]) % 3 == 0)
            {
                f[i].d1 += in[j].x;
                f[i].d2 -= in[j].y;
            }
            if ((i / three[j]) % 3 == 1)
            {
                f[i].d1 -= in[j].x;
                f[i].d2 += in[j].y;
            }
        }
    }

    // 後半 N - N/2 個
    int ko2 = three[n - n / 2];
    vector<status> s(ko2);
    for (int i = 0; i < ko2; i++)
    {
        for (int j = 0; j < n - (n / 2); j++)
        {
            if ((i / three[j]) % 3 == 0)
            {
                s[i].d1 += in[j + (n / 2)].x;
                s[i].d2 -= in[j + (n / 2)].y;
            }
            if ((i / three[j]) % 3 == 1)
            {
                s[i].d1 -= in[j + (n / 2)].x;
                s[i].d2 += in[j + (n / 2)].y;
            }
        }
    }

    // ソートしたうえで半分全列挙をする
    sort(rall(f));
    sort(all(s));
    rmq2 seg(ko2);
    for (int i = 0; i < ko2; i++)
    {
        seg.update(i, s[i].d2);
        // cout<<s[i].d<<' '<<s[i].A.x<<' '<<s[i].A.y<<' '<<s[i].B.x<<' '<<s[i].B.y<<endl;
    }
    ll l = 0, r = 0, ans = 0;
    rep(i, ko1)
    {
        while (l != ko2 && f[i].d1 + s[l].d1 < 0 - d)
        {
            l++;
        }
        while (r != ko2 && f[i].d1 + s[r].d1 <= d)
        {
            r++;
        }
        if (l != r) chmax(ans, (f[i].d2) + seg.query(l, r, 0, 0, seg.nn));
        // cout<<l<<' '<<r<<endl;
        // cout<<f[i].d<<' '<<f[i].A.x<<' '<<f[i].A.y<<' '<<f[i].B.x<<' '<<f[i].B.y<<endl;
        // cout<<ans<<endl;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 5510
memory_kb: 619612
final_rank: 17

code_snippet: #include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>

typedef long long int ll;
typedef std::pair<ll, ll> P;
const int INF = (1<<30);
const ll INFLL = (1LL<<60);
const ll MOD = (ll)(1e9+7);

#define l_ength size

void mul_mod(ll& a, ll b){
	a *= b;
	a %= MOD;
}

void add_mod(ll& a, ll b){
	a = (a<MOD)?a:(a-MOD);
	b = (b<MOD)?b:(b-MOD);
	a += b;
	a = (a<MOD)?a:(a-MOD);
}

ll x[33],y[33];
std::vector<P> v,u;
std::priority_queue<P> pq;

/*
void init(int i=0, int l=0, int r=segsize){
	if(r-l>1){
		init(i*2+1,l,(l+r)/2);
		init(i*2+2,(l+r)/2,r);
		segvalue[i] = std::max(segvalue[i*2+1],segvalue[i*2+2]);
		segrange[i] = P(segrange[i*2+1].first,segrange[i*2+2].second);
	}else{
		segvalue[i] = v[l].second;
		segrange[i] = P(v[l].first,v[l].first);
	}
}

ll query(ll a, ll b, int i=0, int l=0, int r=segsize){
	if(b<segrange[i].first || segrange[i].second<a){
		return -INFLL;
	}
	if(a <= segrange[i].first && segrange[i].second <= b){
		return segvalue[i];
	}
	return std::max(query(a,b,i*2+1,l,(l+r)/2),query(a,b,i*2+2,(l+r)/2,r));
}
*/

void solve(int i, int n, bool flag, ll vl=0ll, ll sc=0ll){
	if(i == n){
		if(flag){
			u.push_back(P(vl,sc));
			// ans = std::max(ans,sc+query(-d-vl,d-vl));
		}else{
			v.push_back(P(vl,sc));
		}
	}else{
		// Annaが取る
		solve(i+1,n,flag,vl-x[i],sc-y[i]);
		// Brunoが取る
		solve(i+1,n,flag,vl+x[i],sc+y[i]);
		// 誰も取らない
		solve(i+1,n,flag,vl,sc);
	}
}

int main(void){
	int n,m,i,j=0;
	ll d,ans=0ll;
	v.reserve(14348907);
	u.reserve(14348907);
	scanf("%d%lld",&n,&d);
	m = n/2;
	for(i=0; i<n; ++i){
		scanf("%lld%lld",&x[i],&y[i]);
	}
	solve(m,n,false);
	solve(0,m,true);
	n = v.l_ength(); m = u.l_ength();
	std::sort(v.begin(),v.end(),std::greater<P>());
	std::sort(u.begin(),u.end());
	// std::cout << n << " " << m << std::endl;
	for(i=0; i<n; ++i){
		while(j<m && u[j].first <= d-v[i].first){
			// std::cout << i << " " << j << std::endl;
			pq.push(P(u[j].second,u[j].first)); ++j;
		}
		while(!pq.empty()){
			if(pq.top().second < (-d-v[i].first)){
				pq.pop();
				continue;
			}
			ans = std::max(ans,pq.top().first+v[i].second);
			break;
		}
	}
	/*
	segsize = v.l_ength();
	init();
	// solve(0,m,true);
	*/
	printf("%lld\n",ans);
	return 0;
}
accuracy: 1
time_ms: 2690
memory_kb: 451332
final_rank: 3

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
 
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
 
 
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
 
#define MOD 1000000007
 
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-8, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;
 
  ModInt() : x(0) {}
 
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
 
  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }
 
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
 
  ModInt operator-() const { return ModInt(-x); }
 
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
 
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
 
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
 
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
 
  bool operator==(const ModInt &p) const { return x == p.x; }
 
  bool operator!=(const ModInt &p) const { return x != p.x; }
 
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
 
  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
 
  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }
 
  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
 
  static int get_mod() { return mod; }
};
 
using modint = ModInt< 1000000007 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;
 
  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }
 
  inline T fact(int k) const { return _fact[k]; }
 
  inline T rfact(int k) const { return _rfact[k]; }
 
  inline T inv(int k) const { return _inv[k]; }
 
  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }
 
  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }
 
  T H(int n, int r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
 
ll modpow(ll x, ll n, ll mod) {
  ll res = 1;
  while(n) {
    if(n&1) res = (res * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return res;
} 
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}
template<typename T> 
struct BIT{
  int N;
  std::vector<T> node;

  BIT(int n){
    N = n;
    node.resize(N+10);
  }

  /* a: 1-indexed */
  void add(int a, T x){
    for(int i=a; i<(int)node.size(); i += i & -i) node[i] += x;
  }

  /* [1, a] */
  T sum(int a){
    T res = 0;
    for(int x=a; x>0; x -= x & -x) res += node[x];
    return res;
  }

  /* [l, r] */
  T rangesum(int l, int r){
    return sum(r) - sum(l-1);
  }

  /* 
    a1+a2+...+aw >= valとなるような最小のwを返す
    @verify https://codeforces.com/contest/992/problem/E
  */
  int lower_bound(T val) {
    if(val < 0) return 0;

    int res = 0;
    int n = 1; 
    while (n < N) n *= 2;

    T tv=0;
    for (int k = n; k > 0; k /= 2) {
      if(res + k < N && node[res + k] < val){
        val -= node[res+k];
        res += k;
      }
    }
    return res+1; 
  }
};
struct UnionFind{
  std::vector<int> par;
  std::vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  int root(int x){
    if(x == par[x]) return x;
    return par[x] = root(par[x]);
  }

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) std::swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};
struct RollingHash{

    using ull = unsigned long long;
    const ull mod = (1ULL << 61) - 1;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;

    const ull MASK61 = mod;

    ull base;
    int n;
    vector<ull> hash, pow;

    RollingHash(const string &s)
    {
        random_device rnd;
        mt19937_64 mt(rnd());
        base = calc_mod(mt()) % 100000 + 1000;
        
        n = (int)s.size();
        hash.assign(n+1, 0);
        pow.assign(n+1, 1);
        
        for(int i=0; i<n; i++){
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
            pow[i+1] = calc_mod(mul(pow[i], base));
        }
    }

    ull calc_mod(ull x){
        ull xu = x >> 61;
        ull xd = x & MASK61;
        ull res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    ull mul(ull a, ull b){
        ull au = a >> 31;
        ull ad = a & MASK31;
        ull bu = b >> 31;
        ull bd = b & MASK31;
        ull mid = ad * bu + au * bd;
        ull midu = mid >> 30;
        ull midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    //[l,r)のハッシュ値
    inline ull get(int l, int r){
        ull res = calc_mod(hash[r] + mod*3-mul(hash[l], pow[r-l]));
        return res;
    }
    //string tのハッシュ値
    inline ull get(string t){
        ull res = 0;
        for(int i=0; i<t.size(); i++){
            res = calc_mod(mul(res, base)+t[i]);
        }
        return res;
    }
    //string s中のtの数をカウント
    inline int count(string t) {
        if(t.size() > n) return 0;
        auto hs = get(t);
        int res = 0;
        for(int i=0; i<n-t.size()+1; i++){
            if(get(i, i+t.size()) == hs) res++; 
        }
        return res;
    }

    /* 
        concat 
        @verify https://codeforces.com/problemset/problem/514/C
    */
    inline ull concat(ull h1, ull h2, int h2len){
      return calc_mod(h2 + mul(h1, pow[h2len]));
    }

    // LCPを求める S[a:] T[b:]
    inline int LCP(int a, int b){
        int len = min((int)hash.size()-a, (int)hash.size()-b);
        
        int lb = -1, ub = len;
        while(ub-lb>1){
            int mid = (lb+ub)/2;

            if(get(a, a+mid) == get(b, b+mid)) lb = mid;
            else ub = mid;
        }
        return lb;
    }
};
template<typename T>
struct segment_tree {
    using F = function<T(T, T)>; // 型Tの値を2つ受け取って型Tの値を返すような関数型

    int n;
    vector<T> node;
    F combine; // 区間の結合を行う演算
    T identity; // 単位元

    segment_tree(int n, F combine, T identity)
        : n(n), node(n<<1, identity), combine(combine), identity(identity) {}

    T operator[](int i) { return node[i + n]; }

    void set(int i, T x) {
        node[i += n] = x;
        // combine関数により、2つの子ノードを結合した結果を親ノードに記録
        while (i >>= 1) node[i] = combine(node[i<<1|0], node[i<<1|1]); 

    }

    T fold(int l, int r) {
        T res = identity; // 初期値は単位元
        for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
            // 区間内のものを左右から結合
            if (l & 1) res = combine(res, node[l++]); 
            if (r & 1) res = combine(node[--r], res);
        }
        return res;
    }
};

ll pow3[30];
int main() {  
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(12);

  int n;
  ll D; cin >> n >> D;
  vector<ll> x(n), y(n);
  REP(i,n) cin >> x[i] >> y[i];
  int n1 = n/2;
  int n2 = n-n1;

  pow3[0] = 1;
  for(int i=1; i<=15; i++) pow3[i] = pow3[i-1] * 3;
  vector<pair<ll,ll>> v;
  REP(bit,pow3[n1]) {
    int t = bit;
    ll s1=0,s2=0;
    REP(i,n1) {
      if(t%3 == 1) {
        s1 += x[i];
        s2 += y[i];
      }else if(t%3 == 2) {
        s1 -= x[i];
        s2 -= y[i];
      }
      t/=3;
    }
    v.push_back({s1,s2});
  }
  sort(all(v));
  vector<ll> a, b;
  REP(i,v.size()) {
    a.push_back(v[i].first);
    b.push_back(v[i].second);
  }
  segment_tree<ll> seg(v.size(), [](ll a, ll b){return max(a, b);}, -(1LL<<60));
  REP(i,v.size()) seg.set(i, b[i]);
  ll ans = -(1LL<<60);
  REP(bit,pow3[n2]) {
    int t = bit;
    ll s1=0,s2=0;
    REP(i,n2) {
      if(t%3 == 1) {
        s1 += x[n1+i];
        s2 += y[n1+i];
      }else if(t%3 == 2) {
        s1 -= x[n1+i];
        s2 -= y[n1+i];
      }
      t/=3;
    }
    ll l = -D-s1, r = D-s1;
    if(l > r) swap(l, r);
    l = lower_bound(all(a), l) - a.begin();
    r = upper_bound(all(a), r) - a.begin();
    if(l == r) continue;
    ans = max(ans, s2 + seg.fold(l, r));
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 5580
memory_kb: 680044
final_rank: 19

code_snippet: #include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PL;
int n;
ll d,x[33],y[33],deq[15000010];
vector<PL> vec[2];
void zen(int idx,int l,int r,ll nx,ll ny){
    if(l >= r) vec[idx].push_back(PL(nx,ny));
    else {
        zen(idx,l+1,r,nx,ny);
        zen(idx,l+1,r,nx+x[l],ny+y[l]);
        zen(idx,l+1,r,nx-x[l],ny-y[l]);
    }
}

int main()
{
    scanf("%d %lld",&n,&d);
    for(int i=0;i<n;i++) scanf("%lld %lld",&x[i],&y[i]);
    
    zen(0,0,n/2,0,0);
    zen(1,n/2,n,0,0);
    
    sort(vec[0].begin(),vec[0].end());
    reverse(vec[0].begin(),vec[0].end());
    sort(vec[1].begin(),vec[1].end());
    
    int s=0,t=0;
    ll ans = 0;
    for(int i=0,j=0;i<vec[0].size();i++){
       while(j < vec[1].size() && vec[0][i].first+vec[1][j].first <= d){
           while(s < t && vec[1][deq[t-1]].second <= vec[1][j].second) t--;
           deq[t++] = j;
           j++;
       }
       while(s < t && vec[0][i].first+vec[1][deq[s]].first < -d) s++;
       if(s < t) ans = max(ans,vec[0][i].second+vec[1][deq[s]].second);
    }
    printf("%lld\n",ans);
    
    return(0);
}
accuracy: 1
time_ms: 2810
memory_kb: 488760
final_rank: 8

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PL;
int n;
ll d,x[33],y[33],deq[15000010];
vector<PL> vec[2];
void zen(int idx,int l,int r,ll nx,ll ny){
    if(l >= r) vec[idx].push_back(PL(nx,ny));
    else {
        zen(idx,l+1,r,nx,ny);
        zen(idx,l+1,r,nx+x[l],ny+y[l]);
        zen(idx,l+1,r,nx-x[l],ny-y[l]);
    }
}

int main()
{
    cin >> n >> d;
    for(int i=0;i<n;i++) cin >> x[i] >> y[i];
    
    zen(0,0,n/2,0,0);
    zen(1,n/2,n,0,0);
    
    sort(vec[0].begin(),vec[0].end());
    reverse(vec[0].begin(),vec[0].end());
    sort(vec[1].begin(),vec[1].end());
    
    int s=0,t=0;
    ll ans = 0;
    for(int i=0,j=0;i<vec[0].size();i++){
       while(j < vec[1].size() && vec[0][i].first+vec[1][j].first <= d){
           while(s < t && vec[1][deq[t-1]].second <= vec[1][j].second) t--;
           deq[t++] = j;
           j++;
       }
       while(s < t && vec[0][i].first+vec[1][deq[s]].first < -d) s++;
       if(s < t) ans = max(ans,vec[0][i].second+vec[1][deq[s]].second);
    }
    cout << ans << endl;
    
    return(0);
}
accuracy: 1
time_ms: 2820
memory_kb: 489252
final_rank: 9

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PL;
int n;
ll d,x[33],y[33],deq[15000010];
vector<PL> vec[2];
void zen(int idx,int l,int r,ll nx,ll ny){
    if(l >= r) vec[idx].push_back(PL(nx,ny));
    else {
        zen(idx,l+1,r,nx,ny);
        zen(idx,l+1,r,nx+x[l],ny+y[l]);
        zen(idx,l+1,r,nx-x[l],ny-y[l]);
    }
}

int main()
{
    cin >> n >> d;
    for(int i=0;i<n;i++) cin >> x[i] >> y[i];
    
    zen(0,0,n/2,0,0);
    zen(1,n/2,n,0,0);
    
    sort(vec[0].begin(),vec[0].end());
    reverse(vec[0].begin(),vec[0].end());
    sort(vec[1].begin(),vec[1].end());
    
    int s=0,t=0;
    ll ans = 0;
    for(int i=0,j=0;i<vec[0].size();i++){
       while(j < vec[1].size() && vec[0][i].first+vec[1][j].first <= d){
           while(s < t && vec[1][deq[t-1]].second <= vec[1][j].second) t--;
           deq[t++] = j;
           j++;
       }
       while(s < t && vec[0][i].first+vec[1][deq[s]].first < -d) s++;
       ans = max(ans,vec[0][i].second+vec[1][deq[s]].second);
    }
    cout << ans << endl;
    
    return(0);
}
accuracy: 0.42857142857142855
time_ms: 2550
memory_kb: 489152
final_rank: 20

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
const int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

int main() {
  int n; ll d; cin >> n >> d;
  vector<ll> x(n), y(n); REP(i, n) cin >> x[i] >> y[i];
  vector<pair<ll, ll> > a;
  function<void(int, ll, ll)> rec1 = [&](int idx, ll val, ll bruno) {
    if (idx == (n >> 1)) {
      a.emplace_back(val, bruno);
      return;
    }
    rec1(idx + 1, val, bruno);
    rec1(idx + 1, val + x[idx], bruno - y[idx]);
    rec1(idx + 1, val - x[idx], bruno + y[idx]);
  };
  rec1(0, 0, 0);
  sort(ALL(a));
  vector<pair<ll, ll> > b;
  function<void(int, ll, ll)> rec2 = [&](int idx, ll val, ll bruno) {
    if (idx == n) {
      b.emplace_back(val, bruno);
      return;
    }
    rec2(idx + 1, val, bruno);
    rec2(idx + 1, val + x[idx], bruno - y[idx]);
    rec2(idx + 1, val - x[idx], bruno + y[idx]);
  };
  rec2(n >> 1, 0, 0);
  sort(ALL(b));
  reverse(ALL(b));
  int p = a.size(), q = b.size();
  deque<int> deq;
  int ba = 0, fr = 0;
  ll ans = 0;
  REP(i, q) {
    while (fr < p && a[fr].first <= d - b[i].first) {
      while (!deq.empty() && a[deq.back()].second <= a[fr].second) deq.pop_back();
      deq.emplace_back(fr++);
    }
    while (ba < fr && a[ba].first < -d - b[i].first) {
      if (deq.front() == ba++) deq.pop_front();
    }
    if (!deq.empty()) chmax(ans, b[i].second + a[deq.front()].second);
  }
  cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 2760
memory_kb: 489204
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1e+15;

class SlideMax {
public:
    deque<pair<ll,ll>> dq;
    SlideMax(){};
    void push(ll val, ll i) {
        while ( ! dq.empty() && dq.back().first <= val) {
            dq.pop_back();
        }
        dq.push_back(make_pair(val, i));
    }
    void pop(ll i) {
        while ( ! dq.empty() && dq.front().second < i) {
            dq.pop_front();
        }
    }
    ll getval() {
        if (dq.empty()) return -INF;
        return dq.front().first;
    }
};

/**
 * dx := Brunoの市場価値 - Annaの市場価値
 * dy := Brunoの貴重度 - Annaの貴重度
 */
void f(int i, int n, ll dx, ll dy, vector<ll> &x, vector<ll> &y, vector<pair<ll,ll>> &res) {
    if (i == n) {
        res.emplace_back(dx, dy);
        return ;
    }
    f(i+1, n, dx, dy, x, y, res); // No one
    f(i+1, n, dx-x[i], dy-y[i], x, y, res); // Anna
    f(i+1, n, dx+x[i], dy+y[i], x, y, res); // Bruno
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N; ll D;
    cin >> N >> D;
    vector<ll> x(N), y(N);
    for (int i=0; i<N; ++i) cin >> x[i] >> y[i];

    vector<pair<ll,ll>> L, R;
    f(0, N/2, 0, 0, x, y, L);
    f(N/2, N, 0, 0, x, y, R);
    sort(L.rbegin(), L.rend());
    sort(R.begin(), R.end());

    SlideMax smax;
    int k = 0;
    ll mx = 0;
    for (int i=0; i<(int)L.size(); ++i) {
        while (k < (int)R.size() && R[k].first <= -L[i].first+D) {
            smax.push(R[k].second, R[k].first);
            k ++;
        }
        smax.pop(-L[i].first-D);
        mx = max(mx, L[i].second + smax.getval());
    }
    cout << mx << endl;

    return 0;
}
accuracy: 1
time_ms: 2760
memory_kb: 489088
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const double eps = 1e-8;
const ll INF = (ll)1e+15;

class SlideMax {
public:
    deque<pair<ll,ll>> dq;
    SlideMax(){};
    void push(ll val, ll i) {
        while ( ! dq.empty() && dq.back().first <= val) {
            dq.pop_back();
        }
        dq.push_back(make_pair(val, i));
    }
    void pop(ll i) {
        while ( ! dq.empty() && dq.front().second < i) {
            dq.pop_front();
        }
    }
    ll getval() {
        if (dq.empty()) return -INF;
        return dq.front().first;
    }
};

/**
 * dx := Brunoの市場価値 - Annaの市場価値
 * dy := Brunoの貴重度 - Annaの貴重度
 */
void f(int i, int n, ll dx, ll dy, vector<ll> &x, vector<ll> &y, vector<pair<ll,ll>> &res) {
    if (i == n) {
        res.emplace_back(dx, dy);
        return ;
    }
    f(i+1, n, dx, dy, x, y, res); // No one
    f(i+1, n, dx-x[i], dy-y[i], x, y, res); // Anna
    f(i+1, n, dx+x[i], dy+y[i], x, y, res); // Bruno
}

int main() {
    int N; ll D;
    cin >> N >> D;

    vector<ll> x(N), y(N);
    for (int i=0; i<N; ++i) cin >> x[i] >> y[i];

    vector<pair<ll,ll>> L, R;
    f(0, N/2, 0, 0, x, y, L);
    f(N/2, N, 0, 0, x, y, R);
    sort(L.rbegin(), L.rend());
    sort(R.begin(), R.end());

    SlideMax smax;
    int k = 0;
    ll mx = 0;
    for (int i=0; i<(int)L.size(); ++i) {
        while (k < (int)R.size() && R[k].first <= -L[i].first+D) {
            smax.push(R[k].second, R[k].first);
            k ++;
        }
        smax.pop(-L[i].first-D);
        mx = max(mx, L[i].second + smax.getval());
    }
    cout << mx << endl;

    return 0;
}
accuracy: 1
time_ms: 2740
memory_kb: 489116
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const double eps = 1e-8;
const ll INF = (ll)1e+15;

ll p3(ll x) {
    return (ll)(pow(3, x) + eps);
}

class SlideMax {
public:
    deque<pair<ll,ll>> dq;
    SlideMax(){};
    void push(ll val, ll i) {
        while ( ! dq.empty() && dq.back().first <= val) {
            dq.pop_back();
        }
        dq.push_back(make_pair(val, i));
    }
    void pop(ll i) {
        while ( ! dq.empty() && dq.front().second < i) {
            dq.pop_front();
        }
    }
    ll getval() {
        if (dq.empty()) return -INF;
        return dq.front().first;
    }
};

void _diff(int i, int n, ll dx, ll dy, vector<ll> &x, vector<ll> &y, vector<pair<ll,ll>> &res) {
    if (i == n) {
        res.emplace_back(dx, dy);
        return ;
    }
    _diff(i+1, n, dx, dy, x, y, res); // No one
    _diff(i+1, n, dx-x[i], dy-y[i], x, y, res); // Anna
    _diff(i+1, n, dx+x[i], dy+y[i], x, y, res); // Bruno
}

/**
 * @return (Brunoの市場価値 - Annaの市場価値, Brunoの貴重度 - Annaの貴重度)
 */
vector<pair<ll,ll>> diff(vector<ll> &x, vector<ll> &y) {
    vector<pair<ll,ll>> res;
    int n = x.size();
    _diff(0, n, 0, 0, x, y, res);
    return res;
}

int main() {
    int N; ll D;
    cin >> N >> D;

    vector<ll> xl(N/2), yl(N/2);
    for (int i=0; i<N/2; ++i) {
        cin >> xl[i] >> yl[i];
    }
    auto L = diff(xl, yl);
    sort(L.rbegin(), L.rend());

    vector<ll> xr((N+1)/2), yr((N+1)/2);
    for (int i=0; i<(N+1)/2; ++i) {
        cin >> xr[i] >> yr[i];
    }
    auto R = diff(xr, yr);
    sort(R.begin(), R.end());

    SlideMax smax;
    int k = 0;
    ll mx = 0;
    for (int i=0; i<(int)L.size(); ++i) {
        while (k < (int)R.size() && R[k].first <= -L[i].first+D) {
            smax.push(R[k].second, R[k].first);
            k ++;
        }
        smax.pop(-L[i].first-D);
        mx = max(mx, L[i].second + smax.getval());
    }
    cout << mx << endl;

    return 0;
}
accuracy: 1
time_ms: 2770
memory_kb: 489164
final_rank: 7

code_snippet: #include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <deque>
#include <tuple>

using lint = long long;

int ipow(int x, int e) {
    return (e == 0 ? 1 : x * ipow(x, e - 1));
}

std::vector<std::pair<lint, lint>> enumerate(int m) {
    std::vector<lint> xs(m), ys(m);
    for (int i = 0; i < m; ++i) {
        std::cin >> xs[i] >> ys[i];
    }

    std::vector<std::pair<lint, lint>> ret;
    for (int t = 0; t < ipow(3, m); ++t) {
        int nt = t;
        lint dx = 0, dy = 0;
        for (int i = 0; i < m; ++i) {
            int k = nt % 3;
            nt /= 3;
            if (k == 0) {
                dx += xs[i];
                dy += ys[i];
            } else if (k == 1) {
                dx -= xs[i];
                dy -= ys[i];
            }
        }
        ret.emplace_back(dx, dy);
    }
    return ret;
}

void solve() {
    int n;
    lint diff;
    std::cin >> n >> diff;

    auto fore = enumerate(n / 2), back = enumerate(n - n / 2);
    std::sort(fore.begin(), fore.end());
    std::sort(back.rbegin(), back.rend());

    lint ans = 0;
    int r = 0;
    std::deque<std::pair<lint, lint>> que;

    for (auto f : fore) {
        lint dx, dy;
        std::tie(dx, dy) = f;

        while (r < (int)back.size() && dx + back[r].first >= -diff) {
            while (!que.empty() &&
                   que.back().second <= back[r].second) {
                que.pop_back();
            }
            que.emplace_back(back[r++]);
        }

        while (!que.empty() &&
               dx + que.front().first > diff) {
            que.pop_front();
        }

        if (!que.empty()) ans = std::max(ans, dy + que.front().second);
    }

    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 4310
memory_kb: 489088
final_rank: 12

code_snippet: #include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <deque>
#include <tuple>

using lint = long long;

int ipow(int x, int e) {
    return (e == 0 ? 1 : x * ipow(x, e - 1));
}

std::vector<std::pair<lint, lint>> enumerate(int m) {
    std::vector<lint> xs(m), ys(m);
    for (int i = 0; i < m; ++i) {
        std::cin >> xs[i] >> ys[i];
    }

    std::vector<std::pair<lint, lint>> ret;
    for (int t = 0; t < ipow(3, m); ++t) {
        int nt = t;
        lint dx = 0, dy = 0;
        for (int i = 0; i < m; ++i) {
            int k = nt % 3;
            nt /= 3;
            if (k == 0) {
                dx += xs[i];
                dy += ys[i];
            } else if (k == 1) {
                dx -= xs[i];
                dy -= ys[i];
            }
        }
        ret.emplace_back(dx, dy);
    }
    return ret;
}

void solve() {
    int n;
    lint diff;
    std::cin >> n >> diff;

    auto fore = enumerate(n / 2), back = enumerate(n - n / 2);
    std::sort(fore.begin(), fore.end());
    fore.erase(std::unique(fore.begin(), fore.end()), fore.end());
    std::sort(back.rbegin(), back.rend());
    back.erase(std::unique(back.begin(), back.end()), back.end());

    lint ans = 0;
    int r = 0;
    std::deque<std::pair<lint, lint>> que;

    for (auto f : fore) {
        lint dx, dy;
        std::tie(dx, dy) = f;

        while (r < (int)back.size() && dx + back[r].first >= -diff) {
            while (!que.empty() &&
                   que.back().second <= back[r].second) {
                que.pop_back();
            }
            que.emplace_back(back[r++]);
        }

        while (!que.empty() &&
               dx + que.front().first > diff) {
            que.pop_front();
        }

        if (!que.empty()) ans = std::max(ans, dy + que.front().second);
    }

    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 4350
memory_kb: 489276
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <deque>
#include <cmath>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> treasure;

int main() {
    int n;
    ll d;
    cin >> n >> d;
    vector<treasure> treasures(n);
    for (int i = 0; i < n; i++) cin >> treasures[i].first >> treasures[i].second;

    vector<treasure> a(pow(3, n / 2));
    for (int i = 0; i < pow(3, n / 2); i++) {
        int tmp = i;
        ll price = 0, value = 0;
        for (int j = 0; j < n / 2; j++) {
            switch (tmp % 3) {
                case 0: {
                    price += treasures[j].first;
                    value += treasures[j].second;
                    break;
                }
                case 1: {
                    price -= treasures[j].first;
                    value -= treasures[j].second;
                    break;
                }
                default:
                    break;
            }
            tmp /= 3;
        }
        a[i].first = price, a[i].second = value;
    }
    sort(a.begin(), a.end(), greater<>());

    vector<treasure> b(pow(3, n - n / 2));
    for (int i = 0; i < pow(3, n - n / 2); i++) {
        int tmp = i;
        ll price = 0, value = 0;
        for (int j = 0; j < n - n / 2; j++) {
            switch (tmp % 3) {
                case 0: {
                    price += treasures[n / 2 + j].first;
                    value += treasures[n / 2 + j].second;
                    break;
                }
                case 1: {
                    price -= treasures[n / 2 + j].first;
                    value -= treasures[n / 2 + j].second;
                    break;
                }
                default:
                    break;
            }
            tmp /= 3;
        }
        b[i].first = price, b[i].second = value;
    }
    sort(b.begin(), b.end());

    int bindex = 0;
    ll ret = 0;
    deque<int> que;
    for (auto x:a) {
        ll upperLimit = d - x.first;
        while (bindex < b.size() && b[bindex].first <= upperLimit) {
            while (!que.empty() && b[que.back()].second <= b[bindex].second)que.pop_back();
            que.push_back(bindex);
            bindex++;
        }

        ll lowerLimit = -d - x.first;
        while (!que.empty() && b[que.front()].first < lowerLimit)que.pop_front();

        if (!que.empty())ret = max(ret, x.second + b[que.front()].second);
    }

    cout << ret << endl;
    return 0;
}
accuracy: 1
time_ms: 5450
memory_kb: 451524
final_rank: 14

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "functional"

using namespace std;

constexpr long long int MOD = 1000000007;
//const int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;

//const double EPS = 1e-8;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;


int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N >> K;
	vector<pair<long long int, long long int>>v(N);
	for (int i = 0; i < N; i++) {
		cin >> v[i].first >> v[i].second;
	}
	vector<pair<long long int, long long int>>a(pow(3, N / 2));
	vector<pair<long long int, long long int>>b(pow(3, N - N / 2));
	for (int i = 0; i < N / 2; i++) {
		int add = pow(3, i);
		for (int j = 0; j < add; j++) {
			a[j + add] = { a[j].first - v[i].first,a[j].second + v[i].second };
			a[j + 2 * add] = { a[j].first + v[i].first,a[j].second - v[i].second };
		}
	}
	for (int i = 0; i < N - N / 2; i++) {
		int add = pow(3, i);
		for (int j = 0; j < add; j++) {
			b[j + add] = { b[j].first - v[i + N / 2].first,b[j].second + v[i + N / 2].second };
			b[j + 2 * add] = { b[j].first + v[i + N / 2].first,b[j].second - v[i + N / 2].second };
		}
	}
	sort(a.begin(), a.end());
	sort(b.begin(), b.end());
	L = R = b.size() - 1;
	deque<long long int>Q;
	multiset<long long int>ms;
	long long int ans = 0;
	for (auto &i : a) {
		while (L >= 0 && i.first + b[L].first >= -K) {
			//ms.insert(-b[L--].second);
			if (Q.empty())Q.push_back(L);
			else {
				while (!Q.empty() && b[Q.back()].second < b[L].second)Q.pop_back();
				Q.push_back(L);
			}
			L--;
		}
		while (R > L&& i.first + b[R].first > K) {
			//ms.erase(ms.find(-b[R--].second));
			if (!Q.empty() && Q.front() == R) {
				Q.pop_front();
			}
			R--;
		}
		//if (!ms.empty())ans = max(ans, i.second - *ms.begin());
		if (!Q.empty())ans = max(ans, i.second + b[Q.front()].second);
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 2460
memory_kb: 451556
final_rank: 2