제출 #1347178

#제출 시각아이디문제언어결과실행 시간메모리
1347178model_codeCollecting Stamps 5 (JOI26_stamps)C++20
100 / 100
964 ms78720 KiB
#include <iostream>
#include <vector>
using namespace std;

int main() {
    cin.tie(0);ios::sync_with_stdio(false);
    int N, D; cin >> N >> D;
    vector<int> T(N);
    for(int i = 0; i < N; i++) cin >> T[i];
    vector<int> ans(N);
    vector<vector<int>> G(N);
    for(int i = 0; i < N-1; i++) {
        int u, v; cin >> u >> v;
        u--; v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    vector<int> dep(N), memo1(N), memo2(N);
    vector<bool> dead(N, false);
    auto calc=[&](int c) -> void {
        dep[c] = 0; memo1[c] = memo2[c] = T[c];
        vector<vector<pair<int, int>>> rd(1);
        rd[0].emplace_back(c, -1);
        auto dfs0=[&](auto && self, int i, int p, int id) -> void {
            dep[i] = dep[p] + 1;
            if(dep[i] > D) return;
            if(rd.size() <= dep[i]) rd.push_back({});
            rd[dep[i]].emplace_back(i, id);
            memo1[i] = min(memo1[p], T[i] - dep[i]);
            memo2[i] = min(memo2[p], T[i] + dep[i]);
            for(int x : G[i]) if(x != p && !dead[x]) {
                self(self, x, i, id);
            }
        };
        vector<int> ch;
        for(int x : G[c]) if(!dead[x]) {
            dfs0(dfs0, x, c, ch.size());
            ch.push_back(x);
        }
        rd[0][0].second = ch.size();
        vector<int> cnt1(ch.size() + 1), cnt2(ch.size() + 1);
        int cnt1_tot = 0, cnt2_tot = 0;
        vector<vector<int>> waiting(rd.size());
        for(int i = 0; i < (int)rd.size(); i++) {
            for(auto [j, id] : rd[i]) {
                cnt1[id] ++;
                cnt1_tot ++;
                if(0 >= memo1[j]) {
                    cnt2[id] ++;
                    cnt2_tot ++;
                } else if(memo1[j] + dep[j] <= D && memo1[j] < (int)rd.size()){
                    waiting[memo1[j]].push_back(id);
                }
            }
        }
        for(int i = 0; i < (int)rd.size(); i++) {
            for(int id : waiting[i]) {
                cnt2[id] ++;
                cnt2_tot ++;
            }
            if(D + 1 - i < rd.size()) {
                for(auto [j, id] : rd[D + 1 - i]) {
                    cnt1[id] --;
                    cnt1_tot --;
                    if(memo1[j] + dep[j] <= D && memo1[j] < (int)rd.size()) {
                        cnt2[id] --;
                        cnt2_tot --;
                    }
                }
            }
            for(auto [j, id] : rd[i]) {
                if(memo2[j] <= i) {
                    ans[j] += cnt1_tot;
                    if(id != ch.size()) ans[j] -= cnt1[id];
                } else {
                    ans[j] += cnt2_tot;
                    if(id != ch.size()) ans[j] -= cnt2[id];
                }
            }
        }
    };
    vector<int> sub(N);
    auto dfs=[&](auto && self, int i, int p) -> void {
        sub[i] = 1;
        for(int x : G[i]) if(x != p && !dead[x]) {
            self(self, x, i);
            sub[i] += sub[x];
        }
    };
    auto find_centroid=[&](auto && self, int i, int p = -1, int tot = -1) -> int {
        if(p == -1) {
            dfs(dfs, i, -1);
            tot = sub[i];
        }
        for(int x : G[i]) if(x != p && !dead[x] && sub[x] * 2 > tot) {
            return self(self, x, i, tot);
        }
        return i;
    };
    auto cent_decomp=[&](auto && self, int i) -> void {
        int c = find_centroid(find_centroid, i);
        calc(c);
        dead[c] = true;
        for(int x : G[c]) if(!dead[x]) {
            self(self, x);
        }
    };
    cent_decomp(cent_decomp, 0);
    for(int x: ans) cout << x << '\n';
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...