제출 #1337976

#제출 시각아이디문제언어결과실행 시간메모리
1337976LudisseyTwo Currencies (JOI23_currencies)C++17
100 / 100
3272 ms43924 KiB
#include <bits/stdc++.h>
#define int long long
#define sz(a) (int)a.size()
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
 
using namespace std;

vector<vector<pair<int,int>>> neigh;
vector<vector<pair<int,pair<int,int>>>> chk;
vector<int> s,e;
vector<int> tour;

void dfs(int x, int p){
    for (auto u : neigh[x])
    {
        if(u.first==p) continue;
        tour.push_back(u.second);
        s[u.first]=sz(tour);
        dfs(u.first,x);
        e[u.first]=sz(tour);
        tour.push_back(u.second);
    }
}

signed main() {
    ios_base::sync_with_stdio(false); cin.tie(nullptr);
    int n,m,q; cin >> n >> m >> q;
    neigh.resize(n);
    s.resize(n);
    e.resize(n);
    chk.resize(n-1);
    for (int i = 0; i < n-1; i++)
    {
        int a,b; cin >> a >> b; a--; b--;
        neigh[a].push_back({b,i});
        neigh[b].push_back({a,i});
    }
    vector<pair<int,int>> s_chk;
    for (int i = 0; i < m; i++)
    {
        int p, c; cin >> p >> c; p--;
        s_chk.push_back({c,p});
    }
    sort(all(s_chk));
    int sq=sqrt(n)*2; 
    int _i=0, _j=0;
    while(_i+sq*_j<m){
        auto p=s_chk[_i+sq*_j];
        chk[p.second].push_back({p.first, {_i, _j}});
        _i++;
        if(_i==sq) _j++, _i=0;
    }
    dfs(0,-1);
    vector<vector<pair<int,int>>> query_block(sq);
    vector<pair<pair<int,int>, pair<int,int>>> query(q);
    vector<pair<int,int>> qs(q);
    vector<int> ans(q); 
    for (int i = 0; i < q; i++)
    {
        int a,b; cin >> a >> b; a--; b--;
        int x,y; cin >> x >> y;
        if(s[a]>s[b]) swap(a,b);
        if(e[a]>e[b]) a=s[a], b=s[b]-1;
        else a=e[a], b=s[b]-1;
        query[i]={{a,b}, {x,y}};
        qs[i]={a,i};
    }
    sort(all(qs));
    int sqm=0;
    _j=0;
    _i=0;
    for (int i = 0; i < sz(tour); i++)
    {
        if(sqm+sz(chk[tour[i]])>sq) _j++, sqm=0;
        sqm+=sz(chk[tour[i]]); 
        while(_i<q&&qs[_i].first==i){
            query_block[_j].push_back({query[qs[_i].second].first.second,qs[_i].second});
            _i++;
        }
    }
    for (int i = 0; i < sz(query_block); i++) sort(all(query_block[i]));
    for (int j = 0; j < sq; j++)
    {
        vector<bool> used(n-1,0);
        vector<int> sm_block(sq,0);
        vector<int> cnt_block(sq,0);
        vector<vector<int>> chk_block(sq,vector<int>(sq));
        int l=0;
        int r=-1;
        int tot=0;
        for (int i = 0; i < sz(query_block[j]); i++)
        {
            int indx=query_block[j][i].second;
            int ql=query[indx].first.first;
            int qr=query[indx].first.second;
            int cx=query[indx].second.first;
            int cy=query[indx].second.second;
            vector<int> add;
            vector<int> rem;
            while(r<qr){
                r++;
                int x=tour[r];
                if(used[x]) rem.push_back(x);
                else add.push_back(x);
                used[x]=!used[x];
                
            }
            while(l<ql){
                int x=tour[l];
                if(used[x]) rem.push_back(x);
                else add.push_back(x);
                used[x]=!used[x];
                l++;
            }
            while(l>ql){
                l--;
                int x=tour[l];
                if(used[x]) rem.push_back(x);
                else add.push_back(x);
                used[x]=!used[x];
            }
            for (auto x : add)
            {
                for (auto u : chk[x])
                {
                    sm_block[u.second.second]+=u.first;
                    cnt_block[u.second.second]++;
                    chk_block[u.second.second][u.second.first]+=u.first;
                    tot++;
                }
            }
            for (auto x : rem)
            {
                for (auto u : chk[x])
                {
                    sm_block[u.second.second]-=u.first;
                    cnt_block[u.second.second]--;
                    chk_block[u.second.second][u.second.first]-=u.first;
                    tot--;
                }
            }
            int csm=0;
            int cnt=0;
            int k=0;
            while(k<sq){
                if(csm+sm_block[k]>cy) break;
                csm+=sm_block[k];
                cnt+=cnt_block[k];
                k++;
            }
            for (int _k = 0; _k < sq && k<sq; _k++)
            {
                if(chk_block[k][_k]+csm>cy) break;
                cnt+=(chk_block[k][_k]>0);
                csm+=chk_block[k][_k];
            }
            cx-=tot-cnt;
            ans[indx]=max(-1LL,cx);
        }
    }
    for (int i = 0; i < q; i++) cout << ans[i] << "\n";
    
    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...