#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define pb push_back
const int N=1e5+5;
vector<int> adj[N];
pair<int,int> road[N],p[N];
map<pair<int,int>,int> c;
int up[N][20],depth[N],gold[N],offset=1,tin[N*4],tout[N*4],tim=0;
void dfs(int node,int par,int d){
depth[node]=d;
up[node][0]=par;
for(int j=1;j<20;j++)up[node][j]=up[up[node][j-1]][j-1];
tin[node]=tim++;
gold[tin[node]]+=gold[tin[par]];
for(auto i:adj[node]){
if(i==par)continue;
gold[tim]+=c[{node,i}];
dfs(i,node,d+1);
}
tout[node]=tim++;
}
int lca(int a,int b){
if(depth[a]<depth[b])swap(a,b);
for(int j=19;j>=0;j--){
if(up[a][j]==0)continue;
if(depth[up[a][j]]>depth[b])a=up[a][j];
}
if(depth[a]>depth[b])a=up[a][0];
if(a==b)return a;
for(int j=19;j>=0;j--){
if(up[a][j]!=up[b][j]){
a=up[a][j];
b=up[b][j];
}
}
return up[a][0];
}
struct node{
pair<int,int> sum={0,0},lazy={0,0}; //lazy.first=plus silver lazy.second=minus gold
node* l=NULL;
node* r=NULL;
};
node* root[N];
void build(node *cur,int l,int r){
if(l==r){
cur->sum.second+=gold[l];
return;
}
cur->l=new node;
cur->r=new node;
int mid=(l+r)/2;
build(cur->l,l,mid);
build(cur->r,mid+1,r);
cur->sum.second=cur->r->sum.second+cur->l->sum.second;
}
void prop(node* cur){
int x=cur->lazy.first,y=cur->lazy.second;
cur->l=new node(*cur->l);
cur->r=new node(*cur->r);
cur->l->lazy.first+=x; cur->l->lazy.second+=y;
cur->l->sum.second+=y; cur->l->sum.first+=x;
cur->r->lazy.first += x; cur->r->lazy.second += y;
cur->r->sum.second += y; cur->r->sum.first += x;
cur->lazy={0,0};
}
node* insert(node* cur,int qlo,int qhi,int l,int r,int plus){
if(l>qhi || r<qlo)return cur;
node* x=new node(*cur);
if(l>=qlo && r<=qhi){
x->sum.first+=plus;
x->sum.second--;
x->lazy.first+=plus; x->lazy.second--;
return x;
}
int mid=(l+r)/2;
prop(x);
x->l=insert(x->l,qlo,qhi,l,mid,plus);
x->r=insert(x->r,qlo,qhi,mid+1,r,plus);
return x;
}
pair<int,int> query(node *cur,int qlo,int qhi,int lo,int hi,pair<int,int> carry={0,0}){
if(lo>=qlo && hi<=qhi)return {cur->sum.first+carry.first,cur->sum.second+carry.second};
if(lo>qhi || hi<qlo)return {0,0};
carry.first+=cur->lazy.first;
carry.second+=cur->lazy.second;
int mid=(lo+hi)/2;
pair<int,int> x=query(cur->l,qlo,qhi,lo,mid,carry);
pair<int,int> y=query(cur->r,qlo,qhi,mid+1,hi,carry);
x.first+=y.first; x.second+=y.second;
return x;
}
signed main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,m,q; cin>>n>>m>>q;
for(int i=0;i<n-1;i++){
int x,y; cin>>x>>y;
road[i]={x,y};
adj[x].pb(y); adj[y].pb(x);
}
for(int i=0;i<m;i++){
int id,cost; cin>>id>>cost; id--;
p[i]={cost,id};
c[road[id]]++;
swap(road[id].first,road[id].second);
c[road[id]]++;
}
sort(p,p+m);
dfs(1,0,0);
while(offset<=tim)offset*=2;
root[0]=new node;
build(root[0],0,offset-1);
for(int i=0;i<m;i++){
int x=road[p[i].second].first,y=road[p[i].second].second;
if(tin[y]>tin[x])x=y;
root[i+1]=insert(root[i],tin[x],tout[x],0,offset-1,p[i].first);
}
while(q--){
int s,t,x,y; cin>>s>>t>>x>>y;
int lc=lca(s,t);
int l=0,r=m;
while(l<r){
int mid=(l+r+1)/2; //all edges with silver<p[mid].first we will pay with silver otherwise gold.
pair<int,int> a=query(root[mid],tin[s],tin[s],0,offset-1);
pair<int,int> b=query(root[mid],tin[t],tin[t],0,offset-1);
pair<int,int> e=query(root[mid],tin[lc],tin[lc],0,offset-1);
int silv=a.first+b.first-e.first*2;
int gld=a.second+b.second-e.second*2;
if(gld<=x && silv<=y)l=mid;
else r=mid-1;
// cout<<l<<' '<<r<<' '<<mid<<' '<<silv<<endl;
}
int mid=l;
pair<int,int> a=query(root[mid],tin[s],tin[s],0,offset-1);
pair<int,int> b=query(root[mid],tin[t],tin[t],0,offset-1);
pair<int,int> e=query(root[mid],tin[lc],tin[lc],0,offset-1);
int silv=a.first+b.first-e.first*2;
int gld=a.second+b.second-e.second*2;
// cout<<l<<' '<<lc<<' '<<gld<<' '<<silv<<' '<<e.first<<' '<<e.second<<endl;
if(gld<=x && silv<=y)cout<<gld<<endl;
else cout<<-1<<endl;
}
}
# | 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... |