This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/// dwuy: _,\,,,_\,__,\,,_
#include <bits/stdc++.h>
#define fastIO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define file(a) freopen(a".inp","r",stdin); freopen(a".out", "w",stdout)
#define fi first
#define se second
#define endl "\n"
#define len(s) int32_t(s.length())
#define MASK(k)(1LL<<(k))
#define TASK ""
#define int long long
using namespace std;
typedef tuple<int, int, int> tpiii;
typedef pair<double, double> pdd;
typedef pair<int, int> pii;
typedef long long ll;
const long long OO = 1e18;
const int MOD = 1e9 + 7;
const int INF = 1e9;
pii operator + (const pii a, const pii b){ return {a.fi + b.fi, a.se + b.se}; }
struct Node{
bool f;
int sum, cnt;
Node *l, *r;
Node(int sum = 0, int cnt = 0){
this->f = 0;
this->sum = sum;
this->cnt = cnt;
this->l = this->r = NULL;
}
Node(Node *other){
this->cnt = other->cnt;
this->sum = other->sum;
this->l = other->l;
this->r = other->r;
}
};
struct persistent_SMT{
int n, m;
vector<Node*> root;
persistent_SMT(int n=0, int m=0){
this->n = n;
this->m = m;
this->root.assign(m+5, NULL);
root[0] = new Node();
}
void update(Node *cur, int l, int r, const int &pos, const int &val){
if(l==r){
cur->sum += val;
cur->cnt += val>0? 1 : -1;
return;
}
int mid = (l+r)>>1;
if(pos<=mid){
cur->l = cur->l? new Node(cur->l) : new Node();
update(cur->l, l, mid, pos, val);
cur->sum = cur->l->sum + (cur->r? cur->r->sum : 0);
cur->cnt = cur->l->cnt + (cur->r? cur->r->cnt : 0);
}
else{
cur->r = cur->r? new Node(cur->r) : new Node();
update(cur->r, mid+1, r, pos, val);
cur->sum = cur->r->sum + (cur->l? cur->l->sum : 0);
cur->cnt = cur->r->cnt + (cur->l? cur->l->cnt : 0);
}
}
void update(int pos, int val, int id){
if(root[id] == NULL) root[id] = new Node(root[id-1]);
update(root[id], 1, n, pos, val);
}
pii get(Node *cur, int l, int r, const int &pos){
if(l>pos || cur==NULL) return {0, 0};
if(r<=pos) return {cur->sum, cur->cnt};
int mid = (l+r)>>1;
return get(cur->l, l, mid, pos) + get(cur->r, mid+1, r, pos);
}
pii get(int pos, int id){
return get(root[id], 1, n, pos);
}
};
const int MX = 200005;
int n, m, q;
pii edges[MX];
pii weight[MX];
vector<int> G[MX];
void nhap(){
cin >> n >> m >> q;
for(int i=1; i<n; i++){
int u, v;
cin >> u >> v;
edges[i] = {u, v};
G[u].push_back(v);
G[v].push_back(u);
}
int e = m;
for(int i=1, t=1; i<=m; i++){
int p, c;
cin >> p >> c;
weight[t] = {c, p};
if(c!=0) t++;
else e--;
}
m = e;
}
int dfsID = 0;
int h[MX];
int p[MX][17];
int num[MX];
int clo[MX];
void dfs(int u){
num[u] = ++dfsID;
h[u] = h[p[u][0]] + 1;
for(int v: G[u]){
if(v == p[u][0]) continue;
p[v][0] = u;
dfs(v);
}
clo[u] = dfsID;
}
int LCA(int u, int v){
if(h[u] > h[v]) swap(u, v);
for(int i=16; i>=0; i--) if(h[p[v][i]] >= h[u]) v = p[v][i];
if(u == v) return u;
for(int i=16; i>=0; i--) if(p[u][i] != p[v][i]){
u = p[u][i];
v = p[v][i];
}
return p[u][0];
}
void solve(){
dfs(1);
for(int j=1; j<=16; j++){
for(int i=1; i<=n; i++){
p[i][j] = p[p[i][j-1]][j-1];
}
}
persistent_SMT smt(n+5, m);
sort(weight+1, weight+1+m);
for(int i=1; i<=m; i++){
int u, v, c = weight[i].fi;
tie(u, v) = edges[weight[i].se];
if(h[u] < h[v]) swap(u, v);
smt.update(num[u], c, i);
smt.update(clo[u]+1, -c, i);
}
for(int i=1; i<=q; i++){
int u, v, g, s;
cin >> u >> v >> g >> s;
int p = LCA(u, v);
pii fp = smt.get(num[p], m);
pii fu = smt.get(num[u], m);
pii fv = smt.get(num[v], m);
int allG = fu.se + fv.se - fp.se*2;
int res = g+1;
for(int lo=0, hi=m; lo<=hi;){
int mid = (lo+hi)>>1;
pii fp = smt.get(num[p], mid);
pii fu = smt.get(num[u], mid);
pii fv = smt.get(num[v], mid);
int numG = allG - (fu.se + fv.se - fp.se*2);
int numS = fu.fi + fv.fi - fp.fi*2;
if(numG > g) lo = mid + 1;
else if(numS > s) hi = mid - 1;
else res = numG, lo = mid + 1;
}
cout << g - res << endl;
}
}
int32_t main(){
fastIO;
//file(TASK);
nhap();
solve();
return 0;
}
/**
5 4 3
1 2
1 3
2 4
2 5
2 9
2 4
3 5
4 7
3 4 2 11
5 3 4 5
2 3 1 1
10 7 9
1 8
6 3
5 9
7 9
3 1
3 4
10 1
2 6
5 6
9 4
7 4
7 4
2 4
7 4
7 4
1 4
8 6 5 3
3 9 8 0
4 7 6 15
7 4 9 3
6 4 8 0
9 10 5 16
5 3 2 4
2 8 4 3
6 1 3 3
**/
# | 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... |