이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct HLD {
bool e; int n, timer; vector<vector<int>> adj;
vector<int> sz, dep, top, pos, par;
HLD(int n, bool edge = 0) : e(edge), n(n), timer(0),
adj(n), sz(n), dep(n), top(n), pos(n), par(n, -1) {}
void add_edge(int x, int y) {
adj[x].push_back(y);
adj[y].push_back(x);
}
void init(int x) {
sz[x] = 1;
for (auto &y : adj[x]) {
dep[y] = dep[x] + 1;
adj[y].erase(find(adj[y].begin(), adj[y].end(), par[y] = x));
init(y);
sz[x] += sz[y];
if (sz[y] > sz[adj[x][0]]) swap(y, adj[x][0]);
}
}
void dfs(int x) {
pos[x] = timer++;
for (auto y : adj[x]) {
top[y] = y == adj[x][0] ? top[x] : y;
dfs(y);
}
}
void build(int r = 0) {
init(r); dfs(r);
}
int lca(int x, int y) {
for (; top[x] != top[y]; x = par[top[x]]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
}
return dep[x] < dep[y] ? x : y;
}
template<class F> void trav_path(int x, int y, F f) {
for (; top[x] != top[y]; x = par[top[x]]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
f(pos[top[x]], pos[x] + 1);
}
if (dep[x] > dep[y]) swap(x, y);
f(pos[x] + e, pos[y] + 1);
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M, Q;
cin >> N >> M >> Q;
vector<vector<pair<int, int>>> adj(N);
HLD hld(N, 1);
vector<pair<int, int>> edges(N - 1);
for (int i = 0; i < N - 1; i++) {
int a, b;
cin >> a >> b;
a--, b--;
edges[i] = {a, b};
adj[a].emplace_back(b, i);
adj[b].emplace_back(a, i);
hld.add_edge(a, b);
}
vector<int> w(N - 1); {
function<void(int, int)> dfs = [&](int x, int p) {
for (auto [y, z] : adj[x]) {
if (y == p) continue;
w[z] = y;
dfs(y, x);
}
};
dfs(0, -1);
}
hld.build();
vector<pair<int, int>> ch(M);
for (int i = 0; i < M; i++) {
int e, s;
cin >> e >> s; e--;
ch[i] = {s, w[e]};
}
sort(ch.begin(), ch.end());
vector<int> S(Q), T(Q), X(Q), ans(Q);
vector<ll> Y(Q);
for (int i = 0; i < Q; i++) {
cin >> S[i] >> T[i] >> X[i] >> Y[i];
S[i]--, T[i]--;
}
vector<int> lo(Q), hi(Q, M);
vector<ll> bit(N + 1);
auto add = [&](int i, ll s) {
for (i++; i <= N; i += i & -i) {
bit[i] += s;
}
};
auto sum = [&](int i) {
ll s = 0;
for (; i; i -= i & -i) s += bit[i];
return s;
};
while (1) {
bool end = 1;
vector<vector<int>> v(M + 1);
for (int i = 0; i < Q; i++) {
if (lo[i] < hi[i]) {
end = 0;
v[(lo[i] + hi[i] + 1) / 2].push_back(i);
}
}
if (end) break;
bit.assign(N + 1, 0);
for (int i = 0; i <= M; i++) {
for (auto j : v[i]) {
ll s = 0;
hld.trav_path(S[j], T[j], [&](int l, int r) {
s += sum(r) - sum(l);
});
s <= Y[j] ? lo[j] = i : hi[j] = i - 1;
}
if (i < M) {
auto [s, j] = ch[i];
add(hld.pos[j], s);
}
}
}
vector<vector<int>> a(M + 1);
for (int i = 0; i < Q; i++) {
a[lo[i]].push_back(i);
}
bit.assign(N + 1, 0);
for (int i = M; i >= 0; i--) {
if (i < M) {
auto [s, j] = ch[i];
add(hld.pos[j], 1);
}
for (auto j : a[i]) {
int cnt = 0;
hld.trav_path(S[j], T[j], [&](int l, int r) {
cnt += sum(r) - sum(l);
});
ans[j] = max<ll>(-1, X[j] - cnt);
}
}
for (int i = 0; i < Q; i++) cout << ans[i] << "\n";
return 6/22;
}
# | 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... |