Submission #933541

#TimeUsernameProblemLanguageResultExecution timeMemory
933541velislavgarkovTwo Currencies (JOI23_currencies)C++14
100 / 100
1700 ms150384 KiB
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
#define endl '\n'
const int MAXN=1e5+10;
struct Edge {
    int a, b, to;
};
struct Checkpoint {
    long long c;
    int subt;
    bool friend operator < (Checkpoint a, Checkpoint b) {
        return a.c<b.c;
    }
};
struct Node {
    long long sum, active;
    int l, r;
};
vector <pair <int,int> > v[MAXN];
Checkpoint p[MAXN];
Edge ed[MAXN];
Node tree[100*MAXN];
int root[MAXN], cnt;
int in[MAXN], out[MAXN], dep[MAXN], sp[MAXN][20];
int n, m, q;
int build_tree(int l, int r) {
    int cur=cnt;
    cnt++;
    tree[cur].sum=tree[cur].active=0;
    if (l==r) return cur;
    int mid=(l+r)/2;
    tree[cur].l=build_tree(l,mid);
    tree[cur].r=build_tree(mid+1,r);
    return cur;
}
int update(int node, int l, int r, int ql, int qr, long long ch) {
    int newc=cnt;
    cnt++;
    tree[newc]=tree[node];
    if (l>=ql && r<=qr) {
        tree[newc].sum+=ch;
        tree[newc].active++;
        return newc;
    }
    int mid=(l+r)/2;
    if (!(ql>mid || qr<l)) tree[newc].l=update(tree[node].l,l,mid,ql,qr,ch);
    if (!(ql>r || qr<mid+1)) tree[newc].r=update(tree[node].r,mid+1,r,ql,qr,ch);
    return newc;
}
long long query(int node, int l, int r, int qind, int type) {
    if (l==r) {
        if (type==0) return tree[node].sum;
        return tree[node].active;
    }
    int mid=(l+r)/2;
    long long res;
    if (qind<=mid) res=query(tree[node].l,l,mid,qind,type);
    else res=query(tree[node].r,mid+1,r,qind,type);
    if (type==0) res+=tree[node].sum;
    else res+=tree[node].active;
    return res;
}
long long check(int curr, int s, int t, int lca, int type) {
    return query(curr,1,n,in[s],type)+query(curr,1,n,in[t],type)-2ll*query(curr,1,n,in[lca],type);
}
void dfs(int x, int p) {
    cnt++;
    in[x]=cnt;
    for (auto i:v[x]) {
        if (i.first==p) continue;
        ed[i.second].to=i.first;
        dep[i.first]=dep[x]+1;
        sp[i.first][0]=x;
        dfs(i.first,x);
    }
    out[x]=cnt;
}
void sparce_table() {
    for (int i=1;(1<<i)<=n;i++) {
        for (int j=1;j<=n;j++) {
            if (sp[j][i-1]==-1) sp[j][i]=-1;
            else sp[j][i]=sp[sp[j][i-1]][i-1];
        }
    }
}
void precomp() {
    cnt=dep[1]=0;
    memset(sp,-1,sizeof(sp));
    dfs(1,-1);
    sparce_table();
    int cur_road;
    for (int i=1;i<=m;i++) {
        cin >> cur_road >> p[i].c;
        p[i].subt=ed[cur_road].to;
    }
    sort(p+1,p+m+1);
    cnt=1;
    root[0]=build_tree(1,n);
    for (int i=1;i<=m;i++) {
        root[i]=update(root[i-1],1,n,in[p[i].subt],out[p[i].subt],p[i].c);
    }
}
int find_lca(int a, int b) {
    if (dep[a]<dep[b]) swap(a,b);
    int st=18;
    while (st>=0) {
        if (sp[a][st]!=-1 && dep[sp[a][st]]>dep[b]) a=sp[a][st];
        st--;
    }
    if (dep[a]!=dep[b]) a=sp[a][0];
    if (a==b) return a;
    st=18;
    while (st>=0) {
        if (sp[a][st]!=-1 && sp[b][st]!=-1 && sp[a][st]!=sp[b][st]) {
            a=sp[a][st];
            b=sp[b][st];
        }
        st--;
    }
    if (a!=b) a=sp[a][0];
    return a;
}
long long solve(int s, int t, long long gold, long long silver) {
    int l, r, mid;
    int lca=find_lca(s,t);
    if (lca==-1) return 0/0;
    l=0; r=m;
    while (l<=r) {
        mid=(l+r)/2;
        if (check(root[mid],s,t,lca,0)<=silver) l=mid+1;
        else r=mid-1;
    }
    long long mi=check(root[m],s,t,lca,1)-check(root[r],s,t,lca,1);
    if (mi<=gold) return gold-mi;
    return -1;
}
int main () {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m >> q;
    for (int i=1;i<=n-1;i++) {
        cin >> ed[i].a >> ed[i].b;
        v[ed[i].a].push_back({ed[i].b,i});
        v[ed[i].b].push_back({ed[i].a,i});
    }
    precomp();
    int s, t;
    long long gold, silver;
    for (int i=0;i<q;i++) {
        cin >> s >> t >> gold >> silver;
        cout << solve(s,t,gold,silver) << endl;
    }
    return 0;
}

Compilation message (stderr)

currencies.cpp: In function 'long long int solve(int, int, long long int, long long int)':
currencies.cpp:129:26: warning: division by zero [-Wdiv-by-zero]
  129 |     if (lca==-1) return 0/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...