Submission #997445

#TimeUsernameProblemLanguageResultExecution timeMemory
997445AbitoTwo Currencies (JOI23_currencies)C++17
100 / 100
415 ms188352 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...