#include <bits/stdc++.h>
#define int long long
#define MAX 200000
#define MAX_LOG 20
using namespace std;
typedef array<int, 2> pr;
int N, edge[MAX][2], depth[MAX], in[MAX], out[MAX], tree[MAX * 4][2], lazy[MAX * 4][2], val[MAX], ecnt[MAX], L[MAX], R[MAX], S[MAX], T[MAX], X[MAX], Y[MAX], ans[MAX], parent[MAX][MAX_LOG], cnt = 0;
vector<pr> adj[MAX];
vector<int> arr[MAX];
pr checkpoint[MAX];
void dfs(int node, int par, int sm) {
    in[node] = ++cnt, val[node] = sm, depth[node] = depth[par] + 1, parent[node][0] = par;
    for (int i = 1; i < MAX_LOG; i++)
        parent[node][i] = parent[parent[node][i - 1]][i - 1];
    for (pr i : adj[node]) {
        if (i[0] == par)
            continue;
        dfs(i[0], node, sm + ecnt[i[1]]);
    }
    out[node] = cnt;
}
void lazy_propagate(int t, int n, int s, int e) {
    if (lazy[n][t] == 0)
        return;
    if (s == e)
        tree[n][t] += lazy[n][t];
    else
        lazy[n << 1][t] += lazy[n][t], lazy[n << 1 | 1][t] += lazy[n][t];
    lazy[n][t] = 0;
}
void update(int t, int n, int s, int e, int l, int r, int v) {
    lazy_propagate(t, n, s, e);
    if (r < s || e < l)
        return;
    else if (l <= s && e <= r)
        lazy[n][t] += v, lazy_propagate(t, n, s, e);
    else {
        int m = s + e >> 1;
        update(t, n << 1, s, m, l, r, v), update(t, n << 1 | 1, m + 1, e, l, r, v);
    }
}
int query(int t, int n, int s, int e, int x) {
    lazy_propagate(t, n, s, e);
    if (x < s || e < x)
        return 0;
    else if (s == e)
        return tree[n][t];
    else {
        int m = s + e >> 1;
        return query(t, n << 1, s, m, x) + query(t, n << 1 | 1, m + 1, e, x);
    }
}
int lca(int x, int y) {
    if (depth[x] < depth[y])
        swap(x, y);
    int diff = depth[x] - depth[y];
    for (int i = MAX_LOG - 1; i >= 0; i--)
        if (diff & (1ll << i))
            diff ^= 1ll << i, x = parent[x][i];
    for (int i = MAX_LOG - 1; i >= 0; i--)
        if (parent[x][i] != parent[y][i])
            x = parent[x][i], y = parent[y][i];
    if (x != y)
        x = parent[x][0];
    return x;
}
int get(int t, int x, int y) {
    int k = lca(x, y);
    if (t == 2)
        return val[x] + val[y] - val[k] * 2;
    return query(t, 1, 1, N, in[x]) + query(t, 1, 1, N, in[y]) - 2 * query(t, 1, 1, N, in[k]);
}
signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int M, Q;
    bool flag;
    cin >> N >> M >> Q;
    for (int i = 1; i < N; i++) {
        cin >> edge[i][0] >> edge[i][1];
        adj[edge[i][0]].push_back({edge[i][1], i}), adj[edge[i][1]].push_back({edge[i][0], i});
    }
    for (int i = 1; i <= M; i++)
        cin >> checkpoint[i][1] >> checkpoint[i][0], ecnt[checkpoint[i][1]]++;
    sort(checkpoint + 1, checkpoint + M + 1);
    dfs(1, 0, 0);
    for (int i = 1; i < N; i++)
        if (depth[edge[i][0]] < depth[edge[i][1]])
            swap(edge[i][0], edge[i][1]);
    for (int i = 1; i <= Q; i++)
        cin >> S[i] >> T[i] >> X[i] >> Y[i], L[i] = 0, R[i] = M, ans[i] = get(2, S[i], T[i]);
    while (true) {
        for (int i = 1; i <= N * 4; i++)
            tree[i][0] = tree[i][1] = lazy[i][0] = lazy[i][1] = 0;
        flag = false;
        for (int i = 1; i <= Q; i++)
            if (L[i] <= R[i])
                arr[L[i] + R[i] >> 1].push_back(i), flag = true;
        if (!flag)
            break;
        for (int i = 0; i <= M; i++) {
            if (i) {
                update(0, 1, 1, N, in[edge[checkpoint[i][1]][0]], out[edge[checkpoint[i][1]][0]], 1);
                update(1, 1, 1, N, in[edge[checkpoint[i][1]][0]], out[edge[checkpoint[i][1]][0]], checkpoint[i][0]);
            }
            for (int j : arr[i]) {
                if (Y[j] >= get(1, S[j], T[j]))
                    L[j] = i + 1, ans[j] = get(2, S[j], T[j]) - get(0, S[j], T[j]);
                else
                    R[j] = i - 1;
            }
            arr[i].clear();
        }
    }
    for (int i = 1; i <= Q; i++) {
        if (ans[i] > X[i])
            cout << -1 << '\n';
        else
            cout << X[i] - ans[i] << '\n';
    }
    return 0;
}
| # | 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... |