Submission #942415

#TimeUsernameProblemLanguageResultExecution timeMemory
942415LOLOLOTwo Currencies (JOI23_currencies)C++17
100 / 100
987 ms89132 KiB
#include <bits/stdc++.h>
#define ll long long
using namespace std;

#define           f     first
#define           s     second
#define           pb    push_back
#define           ep    emplace
#define           eb    emplace_back
#define           lb    lower_bound
#define           ub    upper_bound
#define       all(x)    x.begin(), x.end()
#define      rall(x)    x.rbegin(), x.rend()
#define   uniquev(v)    sort(all(v)), (v).resize(unique(all(v)) - (v).begin())
#define     mem(f,x)    memset(f , x , sizeof(f))
#define        sz(x)    (int)(x).size()
#define  __lcm(a, b)    (1ll * ((a) / __gcd((a), (b))) * (b))
#define          mxx    *max_element
#define          mnn    *min_element
#define    cntbit(x)    __builtin_popcountll(x)
#define       len(x)    (int)(x.length())

const int N = 3e5;
vector <pair <int, int>> ed[N];
int p[N][20], in[N], ou[N], timer = 1, f[N], id[N], val[N], ans[N], cnt[N];

struct fen{
    vector <ll> f;
    int N;
    void ass(int n) {
        N = n;
        f.assign(n + 1, 0);
    }

    void upd(int i, int x) {
        for (; i <= N; i += i & (-i))
            f[i] += x;
    }

    ll get(int u) {
        ll s = 0;
        for (; u; u -= u & (-u))
            s += f[u];

        return s;
    }

    void range(int l, int r, int x) {
        upd(l, x);
        upd(r + 1, -x);
    }   
} f1, f2;

void dfs(int u, int v) {
    timer++;
    in[u] = timer;
    p[u][0] = v;
    for (int i = 1; i < 20; i++) 
        p[u][i] = p[p[u][i - 1]][i - 1];

    for (auto x : ed[u]) {
        if (x.f == v)
            continue;

        id[x.s] = x.f;
        dfs(x.f, u);
    }
    ou[u] = timer;
}

bool is(int a, int b) {
    return in[a] <= in[b] && ou[a] >= ou[b];
}

int lca(int a, int b) {
    if (is(a, b))
        return a;

    if (is(b, a))
        return b;

    for (int i = 19; i >= 0; i--) {
        if (is(p[a][i], b) == 0)
            a = p[a][i];
    }

    return p[a][0];
}

ll sum(int s, int e, fen &f) {
    int c = lca(s, e);
    return f.get(in[s]) + f.get(in[e]) - 2 * f.get(in[c]);
}

vector < pair <int, int>> edge;
int cur = -1;
void move(int m) {
    while (cur > m) {
        int c = edge[cur].s;
        f1.range(in[c], ou[c], -edge[cur].f);
        f2.range(in[c], ou[c], 1);
        cur--;
    }

    while (cur < m) {
        cur++;
        int c = edge[cur].s;
        f1.range(in[c], ou[c], edge[cur].f);
        f2.range(in[c], ou[c], -1);
    }
}

void bin(int l, int r, vector < vector <ll>>& save) {
    if (l > r || save.empty())
        return;

    int m = (l + r) / 2;
    move(m);

    vector < vector <ll>> win, lose;
    for (auto x : save) {
        if (sum(x[0], x[1], f1) <= x[3]) {
            ans[x[4]] = sum(x[0], x[1], f2);
            win.pb(x);
        } else {
            lose.pb(x);
        }
    }

    if (sz(lose))
        bin(l, m - 1, lose);

    if (sz(win))
        bin(m + 1, r, win);
}

int X[N], S[N], T[N];

int main(){
    ios_base::sync_with_stdio(false); 
    cin.tie(0);
    cout.tie(0);

    int n, m, q;
    cin >> n >> m >> q;
    fill(ans, ans + q + 1, 2e9);
    f1.ass(n + 100);
    f2.ass(n + 100);

    for (int i = 1; i < n; i++) {
        int a, b;
        cin >> a >> b;
        ed[a].pb({b, i});
        ed[b].pb({a, i});
    } 

    dfs(1, 1);

    for (int i = 1; i <= m; i++) {
        int p, c;
        cin >> p >> c;
        p = id[p];
        f2.range(in[p], ou[p], 1);
        edge.pb({c, p});
    }

    sort(all(edge));

    vector < vector <ll>> save;
    for (int i = 1; i <= q; i++) {
        ll s, t, x, y;
        cin >> s >> t >> x >> y;
        save.pb({s, t, x, y, i});
        ans[i] = sum(s, t, f2);
        X[i] = x;
        S[i] = s;
        T[i] = t;
    }

    bin(0, sz(edge) - 1, save);
    for (int i = 1; i <= q; i++) {
        if (X[i] < ans[i]) {
            cout << -1 << '\n';
        } else {
            cout << X[i] - ans[i] << '\n';
        }
    }

    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...