이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define F first
#define S second
#define pb push_back
#define ppb pop_back
#define ep insert
#define endl '\n'
#define elif else if
#define pow pwr
#define sqrt sqrtt
#define int long long
#define ll long long
#define y1 YONE
typedef unsigned long long ull;
using namespace std;
const int N=1e5+5,C=1e9;
int n,m,q,lg[2*N],root[N],L[35*N],R[35*N],t,dis[N],f[N],c=1;
pair<int,int> st[20][2*N],seg[35*N];
vector<pair<int,int>> adj[N];
vector<int> v[N];
int newleaf(pair<int,int> v){
seg[++c]=v;
return c;
}
int newnode(int l,int r){
c++;
L[c]=l;
R[c]=r;
seg[c].F=seg[l].F+seg[r].F;
seg[c].S=seg[l].S+seg[r].S;
return c;
}
int edit(int x,int l,int r,int i){
if (l>i || r<i) return x;
if (l==r) return newleaf({seg[x].F+i,seg[x].S+1});
int mid=(l+r)/2;
return newnode(edit(L[x],l,mid,i),edit(R[x],mid+1,r,i));
}
void dfs(int x,int p){
dis[x]=dis[p]+1;
t++;
f[x]=t;
st[0][t]={dis[x],x};
for (auto u:adj[x]){
if (u.F==p) continue;
root[u.F]=root[x];
for (auto y:v[u.S]){
//cout<<u.F<<' '<<y<<endl;
root[u.F]=edit(root[u.F],1,C,y);
}
dfs(u.F,x);
t++;
st[0][t]={dis[x],x};
}return;
}
void build(){
for (int i=1;i<20;i++) for (int j=1;j+(1<<i)<=2*n;j++) st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
return;
}
int query(int l,int r){
if (l>r) swap(l,r);
int i=lg[r-l+1];
return min(st[i][l],st[i][r-(1<<i)+1]).S;
}
int query(int x,int y,int z,int l,int r,int s){
//cout<<x<<' '<<y<<' '<<z<<' '<<l<<' '<<r<<' '<<s<<endl;
if (l==r){
int mx=s/l;
return min(mx,seg[x].S+seg[y].S-2*seg[z].S);
}
int mid=(l+r)/2;
if (seg[L[x]].F+seg[L[y]].F-2*seg[L[z]].F<=s) return seg[L[x]].S+seg[L[y]].S-2*seg[L[z]].S+query(R[x],R[y],R[z],mid+1,r,s-seg[L[x]].F-seg[L[y]].F+2*seg[L[z]].F);
return query(L[x],L[y],L[z],l,mid,s);
}
int32_t main(){
ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
for (int i=2;i<2*N;i++) lg[i]=lg[i/2]+1;
cin>>n>>m>>q;
for (int i=1;i<n;i++){
int x,y;
cin>>x>>y;
adj[x].pb({y,i});
adj[y].pb({x,i});
}
for (int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].pb(y);
}root[1]=1;
dfs(1,0);
build();
while (q--){
int s,t,X,Y;
cin>>s>>t>>X>>Y;
int lca=query(f[s],f[t]);
//cout<<lca<<endl;
int d=seg[root[s]].S+seg[root[t]].S-2*seg[root[lca]].S;
//cout<<seg[root[s]].S<<' '<<seg[root[t]].S<<' '<<seg[root[lca]].S<<endl;
int e=query(root[s],root[t],root[lca],1,C,Y);
//cout<<d<<' '<<e<<endl;
d-=e;
X-=d;
if (X<0) cout<<-1<<endl;
else cout<<X<<endl;
}
return 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... |