#include <bits/stdc++.h>
using namespace std;
// c++ code for the above approach
// Class to store the values of a[i], b[i], a[i] + b[i]
class Triplet {
public:
int a, b, c;
Triplet(int d, int e, int f) {
a = d;
b = e;
c = f;
}
};
// Stores the segment tree
vector<int> seg;
// Function to search floor of
// the current value
int search(vector<Triplet> arr,int val)
{
// Initialise low and high values
int low = 0;
int high = arr.size() - 1;
int ans = -1;
// Perform Binary Search
while (low <= high) {
int mid = low + (high-low)/2;
// If the current value is
// <= val then store the
// candidate answer and
// find for rightmost one
if (arr[mid].a <= val) {
ans = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
return ans;
}
// Function to build segment tree
void build(vector<Triplet> arr,int index,int s,int e)
{
// Base Case
if (s == e) {
seg[index] = arr[s].c;
return;
}
int mid = s + (e - s) / 2;
// Buildthe left and right
// segment trees
build(arr, 2 * index + 1, s, mid);
build(arr, 2 * index + 2, mid + 1, e);
// Update current index
seg[index] = max(seg[2 * index + 1], seg[2 * index + 2]);
}
// Function to get maximum value
// in the range [qs, qe]
int getMax(vector<Triplet> arr,int index,int s,int e,int qs,int qe)
{
// If segment is not in range
if (qe < s || e < qs)
{
return INT_MIN;
}
// If segment is fully in range
if (qs <= s && e <= qe) {
return seg[index];
}
// If a part of this segment is
// in range
int mid = s + (e - s) / 2;
int left = getMax(arr, 2 * index + 1, s, mid, qs, qe);
int right = getMax(arr, 2 * index + 2, mid + 1, e, qs, qe);
// Return the maximum value
return max(left, right);
}
// Function to find the maximum
// possible value according to the
// given condition
void maxValue(vector<int> a,vector<int> b,int n,int k)
{
// Initialize triplet array
vector<Triplet> arr;
// Store the values a[i], b[i],
// a[i] + b[i]
for (int i = 0; i < n; i++) {
arr.push_back(Triplet(a[i], b[i], a[i] + b[i]));
}
// Sort the array according
// to array a[]
sort(arr.begin(), arr.end(), [] (const Triplet &x, const Triplet &y){
return x.a - y.a;
});
// Build segment tree
seg.resize(4*n);
int x = 5;
build(arr, 0, 0, n - 1);
// Initialise the maxvalue of
// the selected pairs
int maxvalue = INT_MIN;
// Traverse the array
for (int i = 0; i < n; i++)
{
// For each value find the
// floor(arr[i] + k)
int right = search(arr, arr[i].a + k);
// Find the maximum value of
// the select pairs i and max
// from (i + 1, right)
if (right != -1) {
maxvalue = max(maxvalue, arr[i].b - arr[i].a + getMax(arr, 0, 0, n - 1, i + 1, right));
}
}
// Print the maximum value
cout << maxvalue - x;
}
// Driver code
int main(){
vector<int> a = {5, 6, 9, 10};
vector<int> b = {3, 0, 10, -10};
int N = 4;
int K = 1;
maxValue(a, b, N, K);
return 0;
}
// This code is contributed by Arushi Jindal.