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