Submission #1108621

#TimeUsernameProblemLanguageResultExecution timeMemory
1108621akim9905Two Currencies (JOI23_currencies)C++17
100 / 100
1629 ms39704 KiB
#include <bits/stdc++.h>
using namespace std;

#define fileio() freopen("input.txt","r",stdin); freopen("output.txt","w",stdout)
#define fio() ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define allr(x) x.rbegin(), x.rend()
#define cmprs(x) sort(all(x)),x.erase(unique(all(x)),x.end())
#define endl "\n"
#define sp " "
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define F first
#define S second
#define rz resize
#define sz(a) (int)(a.size())
#define clr(a) a.clear()

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, ll> pil;
typedef tuple<int, int, int> tpi;
typedef tuple<ll, ll, ll> tpl;
typedef pair<double, ll> pdl;
typedef pair<double, int> pdi;

const int dx[] = {1,-1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
const ll MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MAX = 101010; // PLZ CHK!

inline pll sum(pll a, pll b) {return {a.first+b.first,a.second+b.second};}

struct hld {
    struct segtr{
        //0-indexed!
        vector<pll> tr; int n;
        void rst(int sz) {
            n=sz;
            tr.resize((n+1)<<1,{0,0});
        }

        void upd(int i, ll v) {
            tr[i+n]=sum(tr[i+n],pll{v,1}); i+=n; //AWARE OF UPD POLICY!!
            for (i>>=1; i; i>>=1) tr[i]=sum(tr[i<<1],tr[i<<1|1]);
        }
    
        pll qry(int l, int r) {
            pll ret={0,0};
            for (l+=n, r+=n; l<=r; l>>=1, r>>=1) {
                if (l&1) ret=sum(ret,tr[l++]);
                if (~r&1) ret=sum(ret,tr[r--]);
            }
            return ret;
        }
    };

    int n,pv=0;
    vector<int> sz,dep,par,in,out,top;
    segtr seg;
    vector<vector<int>> g0,g;
    
    void init(int _n) {
        n=_n+10;
        sz.resize(n),dep.resize(n),par.resize(n),top.resize(n),
        in.resize(n),out.resize(n),g0.resize(n),g.resize(n);
        seg.rst(n);
    }

    void dfs0(int cur=1, int prv=-1) {
        for (int nxt:g0[cur]) {
            if (nxt==prv) continue;
            g[cur].pb(nxt);
            dfs0(nxt,cur);
        }
    }

    void dfs1(int cur=1) {
        sz[cur]=1;
        for (int &nxt:g[cur]) {
            par[nxt]=cur;
            dep[nxt]=dep[cur]+1;
            dfs1(nxt);
            sz[cur]+=sz[nxt];
            if (sz[nxt]>sz[g[cur][0]]) swap(nxt,g[cur][0]);
        }
    }

    void dfs2(int cur=1) {
        in[cur]=++pv;
        for (int nxt:g[cur]) {
            top[nxt]=(nxt==g[cur][0]?top[cur]:nxt);
            dfs2(nxt);
        }
        out[cur]=pv;
    }

    pll qry(int a, int b) {
        pll ret={0,0};
        while (top[a]!=top[b]) {
            if (dep[top[a]]<dep[top[b]]) swap(a,b);
            ret=sum(ret,seg.qry(in[top[a]],in[a]));
            a=par[top[a]];
        }
        if (dep[a]>dep[b]) swap(a,b);
        ret=sum(ret,seg.qry(in[a]+1,in[b]));
        return ret;
    }

    void upd(int a, int b, ll v) {
        if (dep[a]<dep[b]) swap(a,b);
        seg.upd(in[a],v);
    }
};

typedef array<ll,4> arr;

int N,M,T;
pii E[MAX];
pll C[MAX];
arr Q[MAX];
int L[MAX],R[MAX],ans[MAX];

int main() {
    fio();
    cin>>N>>M>>T;
    for (int i=0; i<N-1; i++) {
        int u,v; cin>>u>>v;
        E[i]={u,v};
    }
    for (int i=0; i<M; i++) {
        int p,c; cin>>p>>c;
        C[i]={c,p-1};
    }
    for (int i=0; i<T; i++) {
        ll s,t,x,y; cin>>s>>t>>x>>y;
        Q[i]={s,t,x,y};
    }

    sort(C,C+M);
    
    fill(ans,ans+MAX,0);
    fill(L,L+MAX,0);
    fill(R,R+MAX,M-1);
    while (1) {
        bool flg=0;
        vector<int> mid[M+10];
        for (int i=0; i<T; i++) {
            if (L[i]<=R[i]) {
                flg=1;
                mid[L[i]+R[i]>>1].pb(i);
            }
        }
        if (!flg) break;

        hld h; h.init(N);
        for (int i=0; i<N-1; i++) {
            auto [u,v]=E[i];
            h.g0[u].pb(v), h.g0[v].pb(u);
        }
        h.dfs0(), h.dfs1(), h.dfs2();
        
        for (int i=0; i<M; i++) {
            auto [cst,edg]=C[i];
            auto [u,v]=E[edg];
            h.upd(u,v,cst);

            for (int idx:mid[i]) {
                auto [s,t,x,y]=Q[idx];
                auto [sil,cnt]=h.qry(s,t);
                // if (idx==0) cout<<sil<<sp<<cnt<<sp<<y<<endl;
                if (sil<=y) {
                    ans[idx]=max(ans[idx],(int)cnt);
                    L[idx]=i+1;
                }              
                else R[idx]=i-1;  
            }
        }
    }

    // cout<<endl;

    hld h; h.init(N);
    for (int i=0; i<N-1; i++) {
        auto [u,v]=E[i];
        h.g0[u].pb(v), h.g0[v].pb(u);
    }
    h.dfs0(), h.dfs1(), h.dfs2();
    for (int i=0; i<M; i++) {
        auto [cst,edg]=C[i];
        auto [u,v]=E[edg];
        h.upd(u,v,cst);
    }

    for (int i=0; i<T; i++) {
        auto [s,t,x,y]=Q[i];
        auto [sil,cnt]=h.qry(s,t);
        // cout<<s<<sp<<t<<sp<<cnt<<sp<<ans[i]<<endl;
        cout<<max(-1ll,x-(cnt-ans[i]))<<endl;
    }

    return 0;
}

Compilation message (stderr)

currencies.cpp: In function 'int main()':
currencies.cpp:155:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  155 |                 mid[L[i]+R[i]>>1].pb(i);
      |                     ~~~~^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...