Submission #1029524

#TimeUsernameProblemLanguageResultExecution timeMemory
1029524adaawfTwo Currencies (JOI23_currencies)C++17
100 / 100
1494 ms71676 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...