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;
#define int long long
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (b); i >= (a); i --)
#define REP(i, a) for (int i = 0; i < (a); ++i)
#define REPD(i, a) for (int i = (a) - 1; i >= 0; --i)
#define MASK(i) (1LL << (i))
#define BIT(x, i) (((x) >> (i)) & 1)
constexpr ll LINF = (1ll << 60);
constexpr int INF = (1ll << 30);
constexpr int Mod = 1e9 + 7;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
/*
Phu Trong from Nguyen Tat Thanh High School for gifted student
*/
template <class X, class Y>
bool minimize(X &x, const Y &y){
X eps = 1e-9;
if (x > y + eps) {x = y; return 1;}
return 0;
}
template <class X, class Y>
bool maximize(X &x, const Y &y){
X eps = 1e-9;
if (x + eps < y) {x = y; return 1;}
return 0;
}
#define MAX 100005
#define LOG 20
struct Edge{
int u, v;
Edge(){}
Edge(int _u, int _v): u(_u), v(_v){}
int other(int x){return(x ^ u ^ v);}
} edge[MAX];
vector<int> G[MAX];
int numNode, station, citizen;
struct Citizen{
int s, t, gold, silver;
Citizen(){}
Citizen(int _s, int _t, int _gold, int _silver){
s = _s, t = _t, gold = _gold, silver = _silver;
}
} C[MAX];
struct Station{
int id, cost;
Station(){}
Station(int _id, int _cost): id(_id), cost(_cost){}
bool operator < (const Station & oth) const{
return cost < oth.cost;
}
} S[MAX];
int depth[MAX], up[MAX][LOG];
int checkpoint[MAX], cnt[MAX];
int tin[MAX], tout[MAX], timeDfs = 0;
void pre_dfs(int u, int p = -1){
tin[u] = ++timeDfs;
for (int &i : G[u]){
int v = edge[i].other(u);
if(v ^ p){
depth[v] = depth[u] + 1;
up[v][0] = u;
checkpoint[v] = checkpoint[u] + cnt[i];
for (int i = 1; i < LOG; ++i) up[v][i] = up[up[v][i - 1]][i - 1];
pre_dfs(v, u);
}
}
tout[u] = timeDfs;
}
int low_bit(int p){
return p & (-p);
}
int lca(int u, int v){
if (depth[u] < depth[v]) swap(u, v);
int dis = depth[u] - depth[v];
for (; dis > 0; dis ^= low_bit(dis)){
int i = __builtin_ctzll(low_bit(dis));
u = up[u][i];
}
if(u == v) return u;
for (int i = LOG - 1; i >= 0; --i) if(up[u][i] != up[v][i]){
u = up[u][i], v = up[v][i];
}
return up[u][0];
}
pair<int, int> ans[MAX];
struct FenwickTree{
int n;
vector<int> F;
FenwickTree(int _n = 0){
init(_n);
}
void init(int _n = 0){
F.clear();
this -> n = _n;
F.resize(n + 5, 0);
}
int low_bit(int p){
return (p & (-p));
}
void upd(int p, int val){
for (; p <= n; p += low_bit(p)){
F[p] += val;
}
}
int query(int p){
int res = 0;
for (; p > 0; p -= low_bit(p)){
res += F[p];
}
return res;
}
void upd(int l, int r, int v){
upd(l, v); upd(r + 1, -v);
}
};
int finale[MAX];
void process(void){
cin >> numNode >> station >> citizen;
for (int i = 1; i < numNode; ++i){
cin >> edge[i].u >> edge[i].v;
G[edge[i].u].emplace_back(i);
G[edge[i].v].emplace_back(i);
}
for (int i = 1; i <= station; ++i){
cin >> S[i].id >> S[i].cost;
cnt[S[i].id]++;
}
for (int i = 1; i <= citizen; ++i){
cin >> C[i].s >> C[i].t >> C[i].gold >> C[i].silver;
}
pre_dfs(1);
sort(S + 1, S + station + 1);
#define T tuple<int, int, int>
vector<T> candidates;
for (int i = 1; i <= citizen; ++i){
candidates.emplace_back(1, station + 1, i);
}
FenwickTree ft(numNode);
while((int)candidates.size()){
vector<T> nw_candidates;
sort(candidates.begin(), candidates.end());
ft.init(numNode);
int j = 1;
for (T q : candidates){
int lhs, rhs, id;
tie(lhs, rhs, id) = q;
if(lhs == rhs){
ans[id].first = lhs;
continue;
}
int m = (lhs + rhs) >> 1;
while(j <= m){
int i = S[j].id;
int u = (depth[edge[i].v] < depth[edge[i].u] ? edge[i].u : edge[i].v);
ft.upd(tin[u], tout[u], S[j].cost);
++j;
}
int s = C[id].s, t = C[id].t;
if(ft.query(tin[s]) + ft.query(tin[t]) - 2 * ft.query(tin[lca(s, t)]) <= C[id].silver){
nw_candidates.emplace_back(m + 1, rhs, id);
}
else{
nw_candidates.emplace_back(lhs, m, id);
}
}
candidates = move(nw_candidates);
}
for (int i = 1; i <= citizen; ++i) ans[i].second = i;
sort(ans + 1, ans + citizen + 1);
ft.init(numNode);
int j = 1;
for (int i = 1; i <= citizen; ++i){
int id = ans[i].second;
while (j < ans[i].first && j <= station){
int c = S[j].id;
int u = (depth[edge[c].v] < depth[edge[c].u] ? edge[c].u : edge[c].v);
ft.upd(tin[u], tout[u], 1LL);
++j;
}
int s = C[id].s, t = C[id].t;
finale[id] = ft.query(tin[s]) + ft.query(tin[t]) - 2 * ft.query(tin[lca(s, t)]);
}
for (int i = 1; i <= citizen; ++i){
int s = C[i].s, t = C[i].t;
int num_cp = checkpoint[s] + checkpoint[t] - 2 * checkpoint[lca(s, t)];
cout << max(-1LL, C[i].gold - (num_cp - finale[i])) << '\n';
}
}
signed main(){
#define name "Whisper"
cin.tie(nullptr) -> sync_with_stdio(false);
//freopen(name".inp", "r", stdin);
//freopen(name".out", "w", stdout);
process();
return (0 ^ 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... |