This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 1e5 + 5, K = 22;
int n, m, q, x, c[N], ca[N], idx[N], dp[K][N], dep[N], par[N];
ll y;
vector<pii> v[N];
vector<int> rc;
struct node {
ll val;
int cnt;
node *l, *r;
node() : val(0LL), cnt(0), l(nullptr), r(nullptr) {}
node(ll val, int cnt) : val(val), cnt(0), l(nullptr), r(nullptr) {}
};
typedef node* pnode;
pnode rt[N];
void build (int l, int r, pnode &cur) {
cur = new node();
if (l == r) return;
int mid = (l + r) >> 1;
build(l, mid, cur->l);
build(mid + 1, r, cur->r);
}
void upd (int l, int r, pnode &cur, pnode par, int pos, int val) {
cur = new node(*par);
cur->val += val;
cur->cnt++;
if (l == r) return;
int mid = (l + r) >> 1;
if (pos <= mid) upd(l, mid, cur->l, par->l, pos, val);
else upd(mid + 1, r, cur->r, par->r, pos, val);
}
ll qr (int l, int r, pnode add, pnode add2, pnode del, ll val) {
if (l == r) return min((ll) add->cnt + add2->cnt - del->cnt * 2, val / rc[l]);
int mid = (l + r) >> 1;
ll cval = add->l->val + add2->l->val - del->l->val * 2;
int ccnt = add->l->cnt + add2->l->cnt - del->l->cnt * 2;
if (cval >= val) return qr(l, mid, add->l, add2->l, del->l, val);
else return ccnt + qr(mid + 1, r, add->r, add2->r, del->r, val - cval);
}
void dfs (int cur, int par) {
dp[0][cur] = par; dep[cur] = dep[par] + 1;
for (auto &[x, y]: v[cur]) {
if (par == x) continue;
dfs(x, cur); ca[x] = y;
}
}
int lca (int a, int b) {
if (dep[b] > dep[a]) swap(a, b);
for (int i = K - 1; i >= 0; i--) if (dep[dp[i][a]] >= dep[b]) a = dp[i][a];
if (a == b) return a;
for (int i = K - 1; i >= 0; i--) if (dp[i][a] != dp[i][b]) a = dp[i][a], b = dp[i][b];
return dp[0][a];
}
void dfs2 (int cur, int par) {
upd(1, n, rt[cur], rt[par], idx[ca[cur]], rc[ca[cur]]);
for (auto &[x, y]: v[cur]) {
if (par == x) continue;
dfs2(x, cur);
}
}
void solve() {
int s, t;
scanf("%d %d %d %lld", &s, &t, &x, &y);
int lc = lca(s, t);
int cdist = dep[s] + dep[t] - dep[lc] * 2;
int cqr = qr(1, n, rt[s], rt[t], rt[lc], y);
int cw = cdist - cqr;
printf("%d\n", max(x - cw, -1));
}
int main() {
scanf("%d %d %d", &n, &m, &q);
for (int i = 1; i < n; i++) scanf("%d %lld", &x, &y), v[x].emplace_back(y, i), v[y].emplace_back(x, i);
while (m--) scanf("%d %lld", &x, &y), c[x] += y;
for (int i = 1; i < n; i++) if (c[i]) rc.emplace_back(c[i]); rc.emplace_back(0);
sort(rc.begin(), rc.end());
for (int i = 1; i < n; i++) idx[i] = lower_bound(rc.begin(), rc.end(), c[i]) - rc.begin();
dfs(1, 0);
for (int i = 1; i < K; i++) {
for (int j = 1; j <= n; j++) dp[i][j] = dp[i - 1][dp[i - 1][j]];
}
build(1, n, rt[0]); dfs2(1, 0);
while (q--) solve();
}
Compilation message (stderr)
currencies.cpp: In function 'int main()':
currencies.cpp:89:5: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
89 | for (int i = 1; i < n; i++) if (c[i]) rc.emplace_back(c[i]); rc.emplace_back(0);
| ^~~
currencies.cpp:89:66: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
89 | for (int i = 1; i < n; i++) if (c[i]) rc.emplace_back(c[i]); rc.emplace_back(0);
| ^~
currencies.cpp: In function 'void solve()':
currencies.cpp:77:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
77 | scanf("%d %d %d %lld", &s, &t, &x, &y);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp: In function 'int main()':
currencies.cpp:86:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
86 | scanf("%d %d %d", &n, &m, &q);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:87:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
87 | for (int i = 1; i < n; i++) scanf("%d %lld", &x, &y), v[x].emplace_back(y, i), v[y].emplace_back(x, i);
| ~~~~~^~~~~~~~~~~~~~~~~~~
currencies.cpp:88:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
88 | while (m--) scanf("%d %lld", &x, &y), c[x] += y;
| ~~~~~^~~~~~~~~~~~~~~~~~~
# | 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... |