#include "nile.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
typedef long long llong;
const int MAXN = 100000 + 10;
const int MAXLOG = 17;
const llong INF = 1e18;
int n;
struct SegmentTreeMIN
{
	llong tree[4*MAXN];
	void build(int l, int r, int node, llong v[], int t)
	{
		if (l == r)
		{
			if (t == (l & 1)) tree[node] = v[l];
			else tree[node] = INF;
			return;
		}
		int mid = l + r >> 1;
		build(l, mid, 2*node, v, t);
		build(mid + 1, r, 2*node + 1, v, t);
		tree[node] = std::min(tree[2*node], tree[2*node + 1]);
	}
	
	void update(int l, int r, int node, int queryPos, llong queryVal)
	{
		if (l == r)
		{
			tree[node] = queryVal;
			return;
		}
		
		int mid = l + r >> 1;
		if (queryPos <= mid) update(l, mid, 2*node, queryPos, queryVal);
		else update(mid + 1, r, 2*node + 1, queryPos, queryVal);
		tree[node] = std::min(tree[2*node], tree[2*node + 1]);
	}
	llong query(int l, int r, int node, int queryL, int queryR)
	{
		if (queryL <= l && r <= queryR)
		{
			return tree[node];
		}
		int mid = l + r >> 1;
		llong res = INF;
		if (queryL <= mid) res = std::min(res, query(l, mid, 2*node, queryL, queryR));
		if (mid + 1 <= queryR) res = std::min(res, query(mid + 1, r, 2*node + 1, queryL, queryR));
		return res;
	}
	void build(llong v[], int t)
	{
		build(1, n, 1, v, t);
	}
	void update(int idx, llong val)
	{
		update(1, n, 1, idx, val);
	}	
	llong query(int l, int r)
	{
		return query(1, n, 1, l, r);
	}
};
struct Fenwick
{
	int tree[MAXN];
	void build()
	{
		for (int i = 1 ; i <= n ; ++i)
		{
			tree[i]++;
			if (i + (i & (-i)) <= n) tree[i + (i & (-i))] += tree[i];
		}
	}
	void update(int idx, int val)
	{
		assert(idx != 0);
		for (; idx <= n ; idx += idx & (-idx))
		{
			tree[idx] += val;
		}
	}
	int query(int idx)
	{
		int res = 0;
		for (; idx ; idx -= idx & (-idx))
		{
			res += tree[idx];
		}
		return res;
	}
	int findKth(int k)
	{
		int idx = 0;
		for (int lg = MAXLOG - 1 ; lg >= 0 ; --lg)
		{
			if (idx + (1 << lg) <= n && tree[idx + (1 << lg)] < k)
			{
				idx += (1 << lg);
				k -= tree[idx];
			}
		}
		return idx + 1;
	}
};
struct Delivery
{
	int a, b, w;
	friend bool operator < (const Delivery &a, const Delivery &b)
	{
		return a.w < b.w;
	}
};
struct Query
{
	int d, idx;
	friend bool operator < (const Query &a, const Query &b)
	{
		return a.d < b.d;
	}
};
std::vector <std::pair <int,int>> queryBarriers;
std::vector <std::pair <int,int>> barriers;
std::vector <Query> queries;
SegmentTreeMIN treeFull[2];
SegmentTreeMIN treeAdd[2];
llong prefix[MAXN];
Delivery s[MAXN];
Fenwick fenwick;
llong rangeQuery(int l, int r, int d)
{
	llong sum = prefix[r] - prefix[l - 1];
	if ((r - l + 1) % 2 == 0)
	{
		return sum;
	}
	llong ans = sum + treeFull[l & 1].query(l, r);
	if (l + 1 <= r) ans = std::min(ans, sum + treeFull[(l + 1) & 1].query(l, r));
	return ans;
}
llong query(int d)
{
	int last = 1;
	llong answer = 0;
	for (int i = 2 ; i <= n ; ++i)
	{
		if (s[i].w - s[i - 1].w > d)
		{
			answer += rangeQuery(last, i - 1, d);
			last = i;
		}
	}
	answer += rangeQuery(last, n, d);
	return answer;
}
llong v[MAXN];
std::vector <long long> calculate_costs(std::vector <int> W, std::vector <int> A, std::vector <int> B, std::vector <int> E)
{
	n = W.size();
	for (int i = 1 ; i <= n ; ++i)
	{
		s[i].w = W[i - 1];
		s[i].a = A[i - 1];
		s[i].b = B[i - 1];
	}
	std::sort(s + 1, s + 1 + n);
	for (int i = 1 ; i <= n ; ++i)
	{
		prefix[i] = prefix[i - 1] + s[i].b;
	}	
	for (int i = 2 ; i <= n ; ++i)
	{
		barriers.push_back({s[i].w - s[i - 1].w, i});
	}
	for (int i = 2 ; i < n ; ++i)
	{
		queryBarriers.push_back({s[i + 1].w - s[i - 1].w, i});
	}
	int idx = 0;
	std::vector <llong> sol(E.size());
	for (const int &d : E)
	{
		queries.push_back({d, idx++});
	}
	std::sort(queries.begin(), queries.end());
	std::sort(barriers.begin(), barriers.end());
	fenwick.build();
	std::fill(v + 1, v + 1 + n, INF);
	treeAdd[0].build(v, 0);
	treeAdd[1].build(v, 1);
	for (int i = 2 ; i <= n ; i += 2)
	{
		v[i] = s[i].a - s[i].b;
	}
	treeFull[0].build(v, 0);
	std::fill(v + 1, v + 1 + n, INF);
	for (int i = 1 ; i <= n ; i += 2)
	{
		v[i] = s[i].a - s[i].b;
	}
	
	treeFull[1].build(v, 1);
	
	int ptrBar = 0;
	int ptrQBar = 0;
	llong answer = 0;
	for (int i = 1 ; i <= n ; ++i)
	{
		answer += s[i].a;
	}
	for (const auto &[d, idx] : queries)
	{
		while (ptrBar < barriers.size() && barriers[ptrBar].first <= d)
		{
			int pos = barriers[ptrBar].second;
			int cnt = fenwick.query(pos);
			int left = fenwick.findKth(cnt - 1);
			int right = fenwick.findKth(cnt + 1) - 1;
			answer -= rangeQuery(left, pos - 1, d);
			answer -= rangeQuery(pos, right, d);
			answer += rangeQuery(left, right, d);
			fenwick.update(pos, -1);
			ptrBar++;
		}
		
		while (ptrQBar < queryBarriers.size() && queryBarriers[ptrQBar].first <= d)
		{
			int pos = queryBarriers[ptrQBar].first;
			int cnt = fenwick.query(pos);
			int left = fenwick.findKth(cnt - 1);
			int right = fenwick.findKth(cnt + 1) - 1;
			answer -= rangeQuery(left, right, d);
			treeAdd[pos & 1].update(pos, s[pos].a - s[pos].b);
			answer += rangeQuery(left, right, d);
		}
		sol[idx] = answer;
	}
	return sol;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |