// I stand with PALESTINE
// #pragma GCC optimize("Ofast,O3")
// #pragma GCC target("avx,avx2")
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
const ll inf = 1e18;
/*
v[0] - mid + d <= v[1] + mid
max(v[0] - mid + 2d, v[1] - mid + d) <= v[2] + mid
max(v[0] - mid + 3d, v[1] - mid + 2d, v[2] - mid + d) <= v[3] + mid
max(v[0] - mid + 3d, v[1] - mid + 2d, v[2] - mid + d) =
= max(v[0] - mid, v[1] - mid - d, v[2] - mid - 2d) + 3d =
= max(v[0], v[1] - d, v[2] - 2d) + 3d - mid
max(v[0], v[1] - d, v[2] - 2d) + 3d - mid <= v[3] + mid
max(v[0], v[1] - d, v[2] - 2d) + 3d - mid <= v[3] + mid
max(v[0], v[1] - d, v[2] - 2d) + 3d - v[3] <= 2 * mid
(max(v[0], v[1] - d, v[2] - 2d) + 3d - v[3]) / 2 <= mid
*/
void out(ll x) {
cout << x / 2;
if (x % 2) cout << ".5";
cout << ' ';
}
struct lazy {
struct node {
ll val, lazy;
void merge(const node &a, const node &b) {
val = max(a.val, b.val);
lazy = 0;
}
void impact(ll v) {
val += v;
lazy += v;
}
void propagate(node &a, node &b) {
if (lazy != 0) {
a.impact(lazy);
b.impact(lazy);
lazy = 0;
}
}
};
vector<node> tree;
int size;
node neutral_element;
void init(int n) {
size = 1;
while (size < n) size *= 2;
tree.resize(2 * size);
for (int i = size; i < 2 * size; i++) tree[i].val = -inf, tree[i].lazy = 0;
for (int i = size - 1; i > 0; i--) tree[i].merge(tree[i << 1], tree[i << 1 | 1]);
neutral_element.val = -inf, neutral_element.lazy = 0;
}
void upd(int l, int r, ll v, int x, int lx, int rx) {
if (l >= rx or lx >= r) return;
if (l <= lx and rx <= r) {
tree[x].impact(v);
return;
}
tree[x].propagate(tree[x << 1], tree[x << 1 | 1]);
int mid = (lx + rx) >> 1;
upd(l, r, v, x << 1, lx, mid);
upd(l, r, v, x << 1 | 1, mid, rx);
tree[x].merge(tree[x << 1], tree[x << 1 | 1]);
}
void upd(int l, int r, ll v) {
if (l > r) return;
upd(l, r + 1, v, 1, 0, size);
}
node get(int l, int r, int x, int lx, int rx) {
if (l >= rx or lx >= r) return neutral_element;
if (l <= lx and rx <= r) return tree[x];
tree[x].propagate(tree[x << 1], tree[x << 1 | 1]);
int mid = (lx + rx) >> 1;
node ans;
ans.merge(get(l, r, x << 1, lx, mid), get(l, r, x << 1 | 1, mid, rx));
return ans;
}
ll get(int l, int r) {
if (l > r) return -inf;
return get(l, r + 1, 1, 0, size).val;
}
};
struct fenwick {
vector<int> tree;
int n;
void init(int len) {
n = len;
tree.assign(n + 1, 0);
}
void upd(int i, int v) {
for (i++; i <= n; i += i & (-i)) tree[i] += v;
}
int get(int i) {
int sum = 0;
for (i++; i > 0; i -= i & (-i)) sum += tree[i];
return sum;
}
};
void solve() {
int n, m; ll d;
cin >> n >> m >> d;
vector<ll> a(n), b(m);
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < m; i++) cin >> b[i];
auto all = a;
for (int i = 0; i < m; i++) all.emplace_back(b[i]);
sort(all.begin(), all.end());
map<ll, int> mp;
for (ll x: all) mp[x] = lower_bound(all.begin(), all.end(), x) - all.begin();
lazy sg; sg.init(n + m);
lazy sg2; sg2.init(n + m); // sg2 - for max
fenwick fw; fw.init(n + m);
for (int i = 0; i < n; i++) {
int pos = mp[a[i]]++;
sg.upd(pos, pos, -sg.get(pos, pos) + sg2.get(0, pos) + fw.get(pos) * d - a[i]);
sg.upd(pos + 1, n + m - 1, d);
sg2.upd(pos, pos, inf + a[i] - fw.get(pos) * d);
fw.upd(pos, 1);
}
for (int i = 0; i < m; i++) {
int pos = mp[b[i]]++;
sg.upd(pos, pos, -sg.get(pos, pos) + sg2.get(0, pos) + fw.get(pos) * d - b[i]);
sg.upd(pos + 1, n + m - 1, d);
sg2.upd(pos, pos, inf + b[i] - fw.get(pos) * d);
fw.upd(pos, 1);
out(max(0ll, sg.tree[1].val));
}
// auto v = a;
// sort(v.begin(), v.end());
// ll mx = -1e18, ans = 0;
// auto recalc = [&]() -> void {
// mx = -1e18, ans = 0;
// for (int i = 0; i < v.size(); i++) {
// ans = max(ans, mx + i * d - v[i]);
// mx = max(mx, v[i] - i * d);
// }
// };
// recalc();
// for (int i = 0; i < m; i++) {
// if (v.empty() or v.back() <= b[i]) {
// v.emplace_back(b[i]);
// ans = max(ans, mx + ll(v.size() - 1) * d - v.back());
// mx = max(mx, v.back() - ll(v.size() - 1) * d);
// } else {
// v.emplace_back(b[i]);
// sort(v.begin(), v.end());
// recalc();
// }
// out(ans);
// }
}
int main() {
cin.tie(0)->sync_with_stdio(false);
int queries = 1;
#ifdef sunnatov
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
cin >> queries;
#else
// cin >> queries;
#endif
for (int test_case = 1; test_case <= queries; test_case++) {
#ifdef sunnatov
cout << "Test case: " << test_case << endl;
#endif
solve();
cout << '\n';
}
}
# | 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... |