This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define int long long
vector<int> g[100005], gg[100005];
int d[100005], ll[100005][19], u[100005], v[100005], f[100005], res[100005];
int l[100005], r[100005], dd[100005], da[100005], z = 0;
void dfs(int x, int p) {
dd[x] = ++z;
ll[x][0] = p;
for (int w : g[x]) {
if (w == p) continue;
d[w] = d[x] + 1;
dfs(w, x);
}
da[x] = z;
}
void dfs2(int x, int p) {
for (int w : g[x]) {
if (w == p) continue;
f[w] += f[x];
dfs2(w, x);
}
}
int lca(int x, int y) {
if (d[x] < d[y]) swap(x, y);
int k = d[x] - d[y];
for (int i = 18; i >= 0; i--) {
if (k & (1 << i)) {
x = ll[x][i];
}
}
if (x == y) return x;
for (int i = 18; i >= 0; i--) {
if (ll[x][i] != ll[y][i]) {
x = ll[x][i];
y = ll[y][i];
}
}
return ll[x][0];
}
struct QUERY {
int u, v, x, y, h, z;
} b[100005];
pair<int, int> t[400005];
void update(int v, int tl, int tr, int x, int y, int z) {
if (tl == tr) {
t[v].first += y;
t[v].second += z;
return;
}
int mid = (tl + tr) / 2;
if (mid >= x) update(v * 2, tl, mid, x, y, z);
else update(v * 2 + 1, mid + 1, tr, x, y, z);
t[v].first = t[v * 2].first + t[v * 2 + 1].first;
t[v].second = t[v * 2].second + t[v * 2 + 1].second;
}
pair<int, int> sum(int v, int tl, int tr, int l, int r) {
if (l > r) return {0, 0};
if (tl == l && tr == r) {
return t[v];
}
int mid = (tl + tr) / 2;
pair<int, int> h = sum(v * 2, tl, mid, l, min(r, mid)), k = sum(v * 2 + 1, mid + 1, tr, max(l, mid + 1), r);
return {h.first + k.first, h.second + k.second};
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m, q;
cin >> n >> m >> q;
for (int i = 1; i < n; i++) {
cin >> u[i] >> v[i];
g[u[i]].push_back(v[i]);
g[v[i]].push_back(u[i]);
}
dfs(1, 0);
for (int i = 1; i <= 18; i++) {
for (int j = 1; j <= n; j++) {
ll[j][i] = ll[ll[j][i - 1]][i - 1];
}
}
vector<pair<int, int>> vv;
for (int i = 1; i <= m; i++) {
int x, c;
cin >> x >> c;
if (d[u[x]] < d[v[x]]) swap(u[x], v[x]);
vv.push_back({c, u[x]});
f[u[x]]++;
}
dfs2(1, 0);
sort(vv.begin(), vv.end());
for (int i = 1; i <= q; i++) {
cin >> b[i].u >> b[i].v >> b[i].x >> b[i].y;
int h = lca(b[i].u, b[i].v);
res[i] = b[i].z = b[i].x - (f[b[i].u] + f[b[i].v] - f[h] * 2);
l[i] = 0, r[i] = m - 1;
b[i].h = h;
}
while (1) {
for (int i = 0; i < m; i++) gg[i].clear();
for (int i = 1; i <= n * 4; i++) t[i] = {0, 0};
int flag = 0;
for (int i = 1; i <= q; i++) {
if (l[i] <= r[i]) {
flag = 1;
gg[(l[i] + r[i]) / 2].push_back(i);
}
}
if (flag == 0) break;
for (int i = 0; i < m; i++) {
update(1, 1, n, dd[vv[i].second], vv[i].first, 1);
if (da[vv[i].second] != n) update(1, 1, n, da[vv[i].second] + 1, -vv[i].first, -1);
for (int w : gg[i]) {
pair<int, int> p = sum(1, 1, n, 1, dd[b[w].u]), pa = sum(1, 1, n, 1, dd[b[w].v]), pb = sum(1, 1, n, 1, dd[b[w].h]), pp;
pp = make_pair(p.first + pa.first - pb.first * 2, p.second + pa.second - pb.second * 2);
if (pp.first <= b[w].y) {
res[w] = max(res[w], b[w].z + pp.second);
l[w] = i + 1;
}
else r[w] = i - 1;
}
}
}
for (int i = 1; i <= q; i++) cout << max(res[i], -1ll) << '\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... |