Submission #1341215

#TimeUsernameProblemLanguageResultExecution timeMemory
1341215niehTwo Currencies (JOI23_currencies)C++17
100 / 100
1026 ms40740 KiB
#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define FOD(i, a, b) for(int i = (a); i >= (b); i--)
#define file(name) if(fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
#define fi first
#define se second
#define el cout << '\n'
#define maxn int(1e5 + 5)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int LOG = 17;

int n, m, q;

int s[maxn], t[maxn], x[maxn];

ll y[maxn];

int now, tin[maxn], tout[maxn], ver[maxn];

int d[maxn], par[maxn][20];

int l[maxn], r[maxn], res[maxn];

pii e[maxn];

vector<pii> adj[maxn];

vector<int> query[maxn];

int lca(int u, int v) {
    if(d[u] < d[v]) swap(u, v);
    int k = d[u] - d[v];
    FOD(i, LOG, 0) if(k >> i & 1) u = par[u][i];
    if(u == v) return u;
    FOD(i, LOG, 0) if(par[u][i] != par[v][i]) u = par[u][i], v = par[v][i];
    return par[u][0];
}

struct FenwickTree {
    int n;

    vector<ll> t;

    FenwickTree(int __n = 0) {
        n = __n;
        t.assign(n + 3, 0);
    }

    void update(int x, int v) {
        for(; x <= n; x += x & -x) t[x] += v;
    }

    void update(int l, int r, int x) {
        update(l, x);
        update(r + 1, -x);
    }

    ll get(int x) {
        ll res = 0;
        for(; x; x -= x & -x) res += t[x];
        return res;
    }

    ll get(int u, int v) {
        return get(tin[u]) + get(tin[v]) - (get(tin[lca(u, v)]) << 1);
    }
} sum, cnt;

void dfs(int u) {
    tin[u] = ++now;
    for(pii x : adj[u]) {
        int v = x.fi, id = x.se;
        if(v != par[u][0]) {
            ver[id] = v;
            par[v][0] = u;
            d[v] = d[u] + 1;
            dfs(v);
        }
    }
    tout[u] = now;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> n >> m >> q;
    FOR(i, 1, n - 1) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back({ v, i });
        adj[v].push_back({ u, i });
    }
    FOR(i, 1, m) cin >> e[i].se >> e[i].fi;
    FOR(i, 1, q) cin >> s[i] >> t[i] >> x[i] >> y[i];

    sort(e + 1, e + m + 1);
    dfs(1);
    FOR(i, 1, LOG)
        FOR(u, 1, n) par[u][i] = par[par[u][i - 1]][i - 1];

    FOR(i, 1, q) l[i] = 0, r[i] = m, res[i] = -1;
    while(1) {
        bool check = 0;
        FOR(i, 1, q) if(l[i] <= r[i]) {
            check = 1;
            int mid = (l[i] + r[i]) >> 1;
            query[mid].push_back(i);
        }

        if(!check) break;

        sum = cnt = FenwickTree(n);

        FOR(mid, 0, m) {
            if(mid) {
                sum.update(tin[ver[e[mid].se]], tout[ver[e[mid].se]], e[mid].fi);
                cnt.update(tin[ver[e[mid].se]], tout[ver[e[mid].se]], 1);
            }
            for(int id : query[mid]) {
                if(sum.get(s[id], t[id]) <= y[id]) res[id] = cnt.get(s[id], t[id]), l[id] = mid + 1;
                else r[id] = mid - 1;
            }
            query[mid].clear();
        }
    }
    FOR(i, 1, q) cout << max(-1LL, x[i] - (cnt.get(s[i], t[i]) - res[i])), el;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...