// author : daohuyenchi
#ifdef LOCAL
#include "D:\C++ Submit\debug.h"
#else
#define debug(...)
#endif
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define db double
#define i32 int32_t
#define i64 int64_t
#define ll long long
//
#define fi first
#define se second
// #define int long long // consider carefully
//
#define pii pair <int, int>
#define pll pair <ll, ll>
#define PAIR make_pair
#define TUP make_tuple
// TIME IS LIMITED ...
#define rep(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define repd(i, b, a) for (int i = (b), _a = (a); i >= _a; --i)
#define repv(v, H) for(auto &v: H)
// REFLECT ON THE PAST ...
#define RESET(c, x) memset(c, x, sizeof(c))
#define MASK(i) (1LL << (i))
#define BIT(mask, i) (((mask) >> (i)) & 1LL)
#define ONBIT(mask, i) ((mask) | (1LL << (i)))
#define OFFBIT(mask, i) ((mask) &~ (1LL << (i)))
#define COUNTBIT __builtin_popcountll
// 30 / 1 / 2024 ? love is zero... start from zero
#define vi vector <int>
#define vll vector <ll>
#define Lower lower_bound
#define Upper upper_bound
#define all(v) (v).begin(), (v).end()
#define special(H) (H).resize(distance(H.begin(), unique(all(H))))
//
#define sp ' '
#define nl '\n'
#define EL { cerr << '\n'; }
#define yes "YES"
#define no "NO"
#define Log2(n) (63 - __builtin_clzll(n))
#define left __left__
#define right __right__
#define lps(id) ((id) << 1)
#define rps(id) ((id) << 1 | 1)
//____________________________________________________________________
template <class X, class Y> bool maximize(X &a, const Y &b)
{ if(a < b) return a = b, true; else return false; }
template <class X, class Y> bool minimize(X &a, const Y &b)
{ if(a > b) return a = b, true; else return false; }
template <class... T>
void print(T&&... n)
{ using exp = int[]; exp{ 0, (cerr << n << sp, 0)... }; cerr << nl; }
template <class T, class... C>
void assign(int n, T v, C&&... a)
{ using e = int[]; e { (a.assign(n, v), 0)...}; }
template <class... C>
void resize(int n, C&&... a)
{ using e = int[]; e { (a.resize(n), 0)...}; }
template <class T>
using vector2d = vector<vector<T>>;
template <class T>
using vector3d = vector<vector2d<T>>;
template <class T> int ssize(T &a) { return (int) a.size(); }
//____________________________________________________________________
mt19937 rng(chrono::steady_clock().now().time_since_epoch().count());
const long long MOD = 1000000007;
// const int MOD[2] = {1000000009, 998244353};
template<class X> void modmize(X &x, long long cur_Mod = MOD) {
if(x >= cur_Mod) x -= cur_Mod;
if(x < 0) x += cur_Mod;
}
int mod_plus(int A, int B) { modmize(A += B); return A; }
const long long oo = 1e18 + 7;
const long long LINF = 1e18 + 7;
const int IINF = 2e9;
const int nmax = 2e5 + 10;
const int MAX = 1e6;
const int base = 311;
const double eps = 1e-6;
const int block = 500;
static const double PI = acos(-1.0);
//____________________________________________________________________
int n, m, Q;
vector <int> G[nmax];
///////////////////////////////////////////////////////////////////////////////
struct LCA_Euler {
int tour[nmax << 1];
int timer = 0;
int ein[nmax], dep[nmax];
void dfs(int u, int par) {
ein[u] = ++timer;
dep[u] = dep[par] + 1;
tour[timer] = u;
repv (v, G[u]) {
if (v == par) continue;
dfs(v, u);
tour[++timer] = u;
}
}
int min_node(int u, int v) {
return dep[u] <= dep[v] ? u : v;
}
int r_lca[nmax << 1][22];
void build_lca() {
dfs(1, 0);
rep (i, 1, timer) {
r_lca[i][0] = tour[i];
}
rep (k, 1, 18) {
for (int i = 1; i + (1 << k) - 1 <= timer; ++i) {
r_lca[i][k] = min_node(r_lca[i][k - 1], r_lca[i + (1 << (k - 1))][k - 1]);
}
}
}
int get_lca(int u, int v) {
int l = ein[u];
int r = ein[v];
if (l > r) swap(l, r);
int k = Log2(r - l + 1);
return min_node(r_lca[l][k], r_lca[r - (1 << k) + 1][k]);
}
} lca;
///////////////////////////////////////////////////////////////////////////////
array <ll, 4> qs[nmax];
int a[nmax];
pll c[nmax];
array <int, 2> ed[nmax];
int b[nmax];
int dep[nmax], ein[nmax], tour[nmax];
int timer = 0;
void dfs(int u, int p) {
ein[u] = ++timer;
tour[timer] = u;
dep[u] = dep[p] + 1;
repv (v, G[u]) {
if (v == p) continue;
dfs(v, u);
}
}
int pf[nmax];
void dfs2(int u, int p) {
pf[u] = pf[p] + c[u].se;
repv (v, G[u]) {
if (v == p) continue;
dfs2(v, u);
}
}
struct Query {
int l, r, anc, type, id;
bool operator < (const Query &ot) {
return TUP(l / block, r, id) < TUP(ot.l / block, ot.r, ot.id);
}
};
Query query[nmax];
vector <int> zi;
int Lim;
int real_val(int x) {
return zi[x - 1];
}
struct Data {
int l, r;
} T[nmax * 4];
#define pli pair <ll, int>
pair < ll, int > st[nmax * 4];
void build(int id, int l, int r) {
T[id] = {l, r};
if (l == r) return;
int mid = (l + r) / 2;
build(lps(id), l, mid);
build(rps(id), mid + 1, r);
}
pli comb(pli &A, pli &B) {
return PAIR(A.fi + B.fi, A.se + B.se);
}
void upd(int id, int p) {
auto &l = T[id].l;
auto &r = T[id].r;
if (l > p || r < p) return;
if (l == r) {
int sign = p > 0 ? 1 : -1;
p = abs(p);
st[id].fi += real_val(p) * sign;
st[id].se += sign;
return;
}
upd(lps(id), p);
upd(rps(id), p);
st[id] = comb(st[lps(id)], st[rps(id)]);
}
int wot(int id, ll S) {
auto &l = T[id].l;
auto &r = T[id].r;
if (l == r) {
return min <ll> (S / real_val(l), st[id].se);
}
if (st[lps(id)].fi < S) {
return st[lps(id)].se + wot(rps(id), S - st[lps(id)].fi);
}
else {
return wot(lps(id), S);
}
}
bool vis[nmax];
vector <int> List[nmax];
void add(int i) {
int u = tour[i];
if (vis[i] == 0) {
repv (val, List[u]) {
upd(1, val);
}
}
else {
repv (val, List[u]) {
upd(1, - val);
}
}
vis[i] ^= 1;
}
void tintingyn()
{
cin >> n >> m >> Q;
rep (i, 1, n - 1) {
int u, v;
cin >> u >> v;
ed[i] = {u, v};
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1, 0);
lca.build_lca();
rep (i, 1, m) {
cin >> b[i];
int u, v;
tie(u, v, ignore) = TUP(ed[b[i]][0], ed[b[i]][1], 0);
if (dep[u] < dep[v]) swap(u, v);
cin >> a[u];
zi.push_back(a[u]);
debug(u, v, a[u]);
c[u].fi += a[u];
c[u].se ++;
List[u].push_back(a[u]);
}
sort(all(zi));
special(zi);
Lim = ssize(zi);
rep (i, 1, n) {
repv (v, List[i]) {
v = Lower(all(zi), v) - zi.begin() + 1;
}
}
build(1, 1, Lim);
dfs2(1, 0);
rep (i, 0, Q - 1) {
int u, v;
ll x, y;
cin >> u >> v >> x >> y;
if (dep[u] > dep[v]) swap(u, v);
if (ein[u] > ein[v]) swap(u, v);
qs[i] = {u, v, x, y};
int type = 1;
int anc = lca.get_lca(u, v);
if (anc == u) type = 2;
query[i] = {ein[u], ein[v], anc, type, i};
}
sort(query, query + Q);
int L = query[0].l;
int R = L - 1;
vector <int> ans(Q + 2, -1);
rep (_i, 0, Q - 1) {
auto &tv = query[_i];
int l = tv.l;
int r = tv.r;
int anc = tv.anc;
int type = tv.type;
int id = tv.id;
while (L > l) add(--L);
while (R < r) add(++R);
while (L < l) add(L++);
while (R > r) add(R--);
if (type == 2) {
add(ein[anc]);
}
auto S = qs[id][3];
int res = wot(1, S);
int sum = pf[tour[l]] + pf[tour[r]] - pf[anc] * 2;
if (sum - res > qs[id][2]) {
ans[id] = -1;
}
else {
ans[id] = qs[id][2] - (sum - res);
}
if (type == 2) {
add(ein[anc]);
}
}
rep (i, 0, Q - 1) {
cout << ans[i] << nl;
}
}
signed main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
//________________________________________________________________
#define TASK "1"
if(fopen(TASK".inp", "r"))
{ freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); }
//________________________________________________________________
// CODE FROM HERE ...!
int num_test = 1;
// cin >> num_test;
while(num_test--) {
tintingyn();
}
cerr << '\n' << "Time elapsed: " << (1.0 * clock() / CLOCKS_PER_SEC) << " s\n" << nl;
return 0;
}
Compilation message (stderr)
currencies.cpp: In function 'int main()':
currencies.cpp:397:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
397 | { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); }
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:397:47: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
397 | { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); }
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |