제출 #1358899

#제출 시각아이디문제언어결과실행 시간메모리
1358899gkos5678Paprike (COI18_paprike)C++20
13 / 100
98 ms41212 KiB
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define lb lower_bound
#define ff first
#define ss second

typedef long long ll;
typedef pair<ll, int> ii;
typedef vector<int> vi;

const int maxn = 1e5 + 7;

ll n, k, t = 1, h[maxn], in[maxn], ou[maxn], p[18][maxn], sm[maxn], fw[maxn];
bool ins[maxn];
vi ls[maxn];
set<ii> s;

void dfs(int v){
    in[v] = t;
    sm[v] = h[v];
    t++;
    for (int i = 1; i < 18; i++)
        p[i][v] = p[i - 1][p[i - 1][v]];
    for (int ss : ls[v]){
        if (ss == p[0][v]) continue;
        p[0][ss] = v;
        dfs(ss);
        sm[v] += sm[ss];
    }
    ou[v] = t - 1;
    s.insert({-sm[v], v});
}

void upd(int i, ll v){
    for (; i < maxn; i += (i & -i))
        fw[i] += v;
}

ll qu(int i){
    ll ret = 0;
    for (; i > 0; i -= (i & -i))
        ret += fw[i];
    return ret;
}

ll ssum(int v){
    return qu(ou[v]) - qu(in[v] - 1);
}

void rem(int v){
    if (!ins[v]) return;
    ins[v] = 0;
    for (int ss : ls[v]){
        if (ss == p[0][v]) continue;
        rem(ss);
    }
}

int main(){
//    ios_base::sync_with_stdio(0);
//    cin.tie(0); cout.tie(0);

    cin >> n >> k;
    for (int i = 1; i <= n; i++){
        cin >> h[i];
        ins[i] = 1;
    }
    for (int i = 1; i < n; i++){
        int x, y;
        cin >> x >> y;
        ls[x].pb(y);
        ls[y].pb(x);
    }

    p[0][1] = 1;
    dfs(1);
    for (int i = 1; i <= n; i++)
        upd(in[i], h[i]);
    ll uk = sm[1], ans = 0;
    while(uk > k){
        ii njb = *s.lb({-k, 0});
        s.erase(s.find(njb));
        int v = njb.ss;
        ll sb = -njb.ff;
        if (!ins[v]){
            continue;
        }
        if (sb != ssum(v)){
            continue;
        }
        ans++;
        uk -= sb;
        upd(in[v], -sb);
        rem(v);
        int sv = v;
        for (int i = 17; i >= 0; i--){
            int nv = p[i][v];
            if (ssum(nv) <= k)
                v = nv;
        }
        if (sv != v) s.insert({-ssum(v), v});
    }

    cout << ans << "\n";
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…