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;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
#define ff first
#define ss second
#define pb push_back
#define all(x) (x).begin(),(x).end()
const int nax = 1e5 + 4;
int n, m, q, k = 1;
vector<pii> adj[nax];
vector<pair<ll,int>> checkp;
vector<ll> st, lazy;
int eul[nax], ed[nax], sp[nax][20], d[nax], head[nax];
int S[nax], T[nax], C[nax];
ll X[nax], Y[nax];
int cureul = -1;
void propagate(int p, int l, int r)
{
if(lazy[p] != 0)
{
if(l != r)
{
lazy[2 * p] +=lazy[p];
lazy[2 * p + 1] += lazy[p];
}
st[p] += lazy[p] * 1ll * (r - l + 1);
lazy[p] = 0ll;
}
}
void update(int p, int l, int r, int i, int j, ll val)
{
propagate(p, l, r);
if(i > j)
return;
if(l >= i && r<= j)
{
lazy[p] += val;
propagate(p, l, r);
return ;
}
int mid = (l + r)/2;
update(2 * p, l, mid, i, min(j, mid), val);
update(2 * p + 1, mid + 1, r, max(i, mid + 1), j, val);
ll lsubtree = st[2 * p] + lazy[2 * p] * 1ll * (mid - l + 1ll);
ll rsubtree = st[2 * p + 1] + lazy[2 * p + 1] * 1ll * (r - mid);
st[p] = lsubtree + rsubtree;
}
ll query(int p, int l, int r, int i, int j)
{
propagate(p, l,r );
if(i > j)
return 0ll;
if(l >= i && r <= j)
return st[p];
int mid = (l + r)/2;
return query(2 * p, l, mid, i, min(j, mid))
+ query(2 * p + 1, mid + 1, r, max(i, mid + 1), j);
}
void dfs(int x, int p = 0)
{
sp[x][0] = p;
d[x]= d[p] + 1;
eul[x] = ++cureul;
for(auto e: adj[x])
{
if(e.ff == p)
continue;
head[e.ss] = e.ff;
dfs(e.ff, x);
}
ed[x]= cureul;
}
void build()
{
for(int j = 1; j < 20; j++)
for(int i =1; i <= n; i++)
sp[i][j] = sp[sp[i][j - 1]][j - 1];
}
int jump(int a, int k)
{
for(int i = 0; i < 20; i++)
if((1 << i) & k)
a = sp[a][i];
return a;
}
int lca(int a, int b)
{
if(d[a] < d[b])
swap(a, b);
a = jump(a, d[a] - d[b]);
if(a == b)
return a;
for(int i = 19; i >= 0; i--)
if(sp[a][i] != sp[b][i])
a = sp[a][i], b= sp[b][i];
return sp[a][0];
}
int cur = -1;
vector<vector<int>> QE;
int rep[nax], ans[nax];
vector<int> COR[nax];
void bsearch(int l, int r, int idx =0)
{
if(QE[idx].empty())
return ;
if(l > r)
{
QE[idx].clear();
return ;
}
// cout << l << ' ' << r << endl;
int mid = (l + r)/2;
if(cur < mid)
{
for(cur++; cur <= mid; cur++)
{
int x = checkp[cur].ss;
ll V = checkp[cur].ff;
update(1, 0, k - 1, eul[x], ed[x], V);
}
cur--;
}
else
{
for(; cur > mid; cur--)
{
int x = checkp[cur].ss;
ll V = checkp[cur].ff;
update(1, 0, k - 1, eul[x], ed[x], -V);
}
}
vector<int> L, R;
for(auto e: QE[idx])
{
ll path = query(1, 0, k - 1, eul[S[e]], eul[S[e]])
+ query(1, 0, k - 1, eul[T[e]], eul[T[e]])
- 2ll * query(1, 0, k - 1, eul[C[e]], eul[C[e]]);
if(path <= Y[e])
{
//cout <<mid << ' ' << e << ' ' << path << ' ' << S[e] << ' ' << T[e] <<' ' << C[e] << endl;
rep[e] = mid;
R.pb(e);
}
else
L.pb(e);
}
QE[idx].clear();
if(!L.empty())
{
QE.pb(L);
L.clear();
bsearch(l, mid - 1, (int)(QE.size()) - 1);
}
if(!R.empty())
{
QE.pb(R);
R.clear();
bsearch(mid + 1, r, (int)(QE.size()) - 1);
}
return;
}
void solve()
{
cin >> n >> m >> q;
for(int i= 1; i < n; i++)
{
int a, b;
cin >> a >> b;
adj[a].pb({b, i});
adj[b].pb({a, i});
}
dfs(1, 0);
build();
while(k < n)
k = (k << 1);
st.assign(2 * k + 1, 0ll);
lazy.assign(2 * k + 1, 0ll);
for(int i = 0; i < m; i++)
{
int p; cin >> p;
ll c; cin >> c;
checkp.pb({c, head[p]});
}
sort(all(checkp));
QE.pb({});
for(int i = 0; i < q; i++)
{
cin >> S[i] >> T[i] >> X[i] >> Y[i];
C[i]= lca(S[i], T[i]);
QE[0].pb(i);
rep[i] = -1;
}
bsearch(0, m - 1);
st.assign(2 * k + 1, 0ll);
lazy.assign(2 * k + 1, 0ll);
for(int i =0; i < q; i++)
COR[rep[i] + 1].pb(i);
for(int i = m - 1; i >= 0; i--)
{
int x = checkp[i].ss;
update(1, 0, k- 1, eul[x], ed[x], 1);
for(auto e: COR[i])
{
int a= query(1, 0, k -1, eul[S[e]], eul[S[e]]);
int b = query(1, 0, k - 1, eul[T[e]], eul[T[e]]);
int c = query(1, 0, k -1, eul[C[e]], eul[C[e]]);
ans[e] = a + b - 2 * c;
//cout << e << ' ' << ans[e] << '\n';
}
}
for(int i = 0; i< q; i++)
{
if(ans[i] > X[i])
cout << "-1\n";
else
cout << X[i] - ans[i] << '\n';
}
}
int32_t main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int tt = 1;
while(tt--)
solve();
}
# | 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... |