#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double dou;
#define pii pair<int, int>
#define fi first
#define se second
#define pb push_back
#define BITJ(x, j) (((x)>>(j))&1)
#define MASK(j) (1LL<<(j))
#define ALL(v) v.begin(), v.end()
template<typename T> bool maximize(T &x, const T &y) {
if (x < y) {x = y; return 1;}
return 0;
}
template<typename T> bool minimize(T &x, const T &y) {
if (x > y) {x = y; return 1;}
return 0;
}
struct BIT{
int n;
vector<ll> bit;
void init(int _n) {
n = _n;
bit.assign(n+1, 0);
}
void upd(int k, ll x) {
while (k <= n) {
bit[k] += x;
k += k & (-k);
}
}
void update(int l, int r, ll x) {
upd(l, x);
upd(r+1, -x);
}
ll getsum(int k){
ll res = 0;
while (k > 0) {
res += bit[k];
k -= k & (-k);
}
return res;
}
};
struct query{
int u, v, lca;
ll gold, silver, ans = -1;
query(int _u, int _v, int _lca, ll _gold, ll _silver) {
u = _u;
v = _v;
lca = _lca;
gold = _gold;
silver = _silver;
}
};
const int maxn = 1e5+5, lg = 17;
int n, m, q;
vector<pii> edges;
vector<int> adj[maxn];
int tin[maxn], tout[maxn], timer = 0, h[maxn], par[maxn][lg];
BIT bit, bitcnt;
vector<pair<ll,int>> updates; //val, node, sort by val
vector<query> qu;
void dfsprep(int u, int p) {
for (int j = 1; j < lg; j++) {
if (MASK(j) >= h[u]) continue;
par[u][j] = par[par[u][j-1]][j-1];
}
tin[u] = ++timer;
for (int v : adj[u]) {
if (v == p) continue;
par[v][0] = u;
h[v] = h[u] + 1;
dfsprep(v, u);
}
tout[u] = timer;
}
bool inside(int u, int v){
return (tin[u] <= tin[v] && tout[v] <= tout[u]);
}
int findlca(int u, int v) {
if (inside(u, v)) return v;
if (inside(v, u)) return u;
for (int j = lg-1; j >= 0; j--){
while (MASK(j) < h[u] && !inside(par[u][j], v)) {
u = par[u][j];
}
}
return par[u][0];
}
void prlbs() {
vector<int> bleft, bright, bmid, id;
//update val, update 1
bleft.assign(q, 0);
bright.assign(q, m);
bmid.assign(q, m/2);
while (true) {
bool can = 0;
id.clear();
for (int i = 0; i < q; i++) {
if (bleft[i] <= bright[i]) {
can = 1;
bmid[i] = (bleft[i]+bright[i])>>1;
id.pb(i);
}
}
if (!can) break;
sort(ALL(id), [&](int a, int b){return bmid[a] < bmid[b];});
int j = 0;
bit.init(n);
bitcnt.init(n);
for (int i = 0; i < m; i++) {
int u = updates[i].se;
bitcnt.update(tin[u], tout[u], 1);
}
for (int i : id){
while (j < bmid[i]) {
int u = updates[j].se;
bit.update(tin[u], tout[u], updates[j].fi);
bitcnt.update(tin[u], tout[u], -1);
++j;
}
// cout << "mid " << bmid[i] << "\n";
ll sum = bit.getsum(tin[qu[i].u])+bit.getsum(tin[qu[i].v]);
sum -= bit.getsum(tin[qu[i].lca])*2;
// cout << sum << "\n";
if (sum > qu[i].silver) {
//case too much
bright[i] = bmid[i]-1;
continue;
}
int cnt = bitcnt.getsum(tin[qu[i].u])+bitcnt.getsum(tin[qu[i].v]);
sum -= bitcnt.getsum(tin[qu[i].lca])*2;
// cout << cnt << "\n";
if (cnt > qu[i].gold){
//case too low
bleft[i] = bmid[i]+1;
continue;
}
//case ok, try to find if there is any optimal solution
maximize(qu[i].ans, qu[i].gold-cnt);
bleft[i] = bmid[i]+1;
}
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
// #define name "task"
// if (fopen(name".inp", "r")) {
// freopen(name".inp", "r", stdin);
// freopen(name".out", "w", stdout);
// }
//input
cin >> n >> m >> q;
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
edges.pb({u, v});
adj[u].pb(v);
adj[v].pb(u);
}
//dfs tin tout
h[1] = 1;
dfsprep(1, -1);
//take updates, rephrase, sort
for (int i= 1; i <= m; i++) {
int p;
ll x;
cin >> p >> x;
--p;
int u = tin[edges[p].fi] > tin[edges[p].se] ? edges[p].fi : edges[p].se;
// cout << p << ' ' << u << "\n";
updates.pb(make_pair(x, u));
}
sort(ALL(updates));
//take queries
for (int i= 1; i <= q; i++) {
int u, v;
ll gold, silver;
cin >> u >> v >> gold >> silver;
// cout << u << ' ' << v << ' ' << findlca(u, v) << "\n";
qu.pb(query(u, v, findlca(u, v), gold, silver));
}
//parallel binsearch
prlbs();
//output
for (int i = 0; i < q; i++) {
cout << qu[i].ans << "\n";
}
}
/*
5 4 1
1 2
1 3
2 4
2 5
2 9
2 4
3 5
4 7
3 4 2 11
5 4 3
1 2
1 3
2 4
2 5
2 9
2 4
3 5
4 7
3 4 2 11
5 3 4 5
2 3 1 1
*/
# | 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... |