제출 #1365499

#제출 시각아이디문제언어결과실행 시간메모리
1365499enzyPetrol stations (CEOI24_stations)C++20
37 / 100
290 ms23964 KiB
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
const int maxn=7e4+10;
int sub[maxn], tam, marc[maxn], ja[maxn], pai[maxn], k;
vector<pii>v[maxn];
void dfs(int u){
    tam++; marc[u]++;
    sub[u]=1;
    for(pii p : v[u]){
        if(marc[p.fi]) continue;
        pai[p.fi]=u;
        dfs(p.fi);
        sub[u]+=sub[p.fi];
    }
}
int find_cd(int u){
    tam=0;
    pai[u]=0;
    dfs(u);
    int nxt=-1, at=u;
    while(true){
        // cerr << "> " << at << ' ' << sub[at] << '\n';
        bool flag=true;
        for(pii p : v[at]) if(ja[p.fi]==0&&p.fi!=pai[at]&&2*sub[p.fi]>tam) flag=false, nxt=p.fi;
        if(flag) return at;
        at=nxt; nxt=-1;
    }
}
vector<int>cd_decomp(int n){ // me parece certo o suficiente
    int qtd=0;
    vector<int>ret;
    while(qtd!=n){
        // cerr << "? " << qtd << '\n';
        for(int i=0;i<n;i++) marc[i]=0;
        for(int x : ret) marc[x]=1;
        for(int i=0;i<n;i++){
            if(!marc[i]){
                int at=find_cd(i);
                ret.push_back(at);
                ja[at]++;
                qtd++;
            }
        }
    }
    return ret;
}

int cnt[maxn][11], cost[maxn], special[11], blocked[maxn], resp[maxn], n_sub[maxn], M=0, ttt;

void go(int u, int pai){
    // cerr << "visiting " << u << '\n';
    assert(!blocked[u]);
    int past[k+1];
    for(int i=0;i<=k;i++) past[i]=special[i];
    // for(int i=0;i<=k;i++) cerr << past[i] << ' ';
    // cerr << '\n';
    for(pii p : v[u]){
        if(p.fi==pai||blocked[p.fi]) continue;
        for(int i=0;i<p.se;i++) resp[u]+=past[i]*n_sub[p.fi];
        // cerr << "!!! ";
        // for(int i=0;i<=k;i++) cerr << past[i] << ' ';
        // cerr << '\n';
        for(int i=0;i<=k;i++) special[i]=0;
        for(int i=0;i<p.se;i++) special[k-p.se]+=past[i];
        for(int i=p.se;i<=k;i++) special[i-p.se]+=past[i];
        // cerr << "$$$ ";
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';
        go(p.fi,u);
    }
}

void pre(int u, int pai){
    ttt++;
    n_sub[u]=1;
    // cerr << "> " << u << '\n';
    for(int i=0;i<=k;i++) cnt[u][i]=0;
    cnt[u][k]=1;
    for(pii p : v[u]){
        if(blocked[p.fi]||p.fi==pai) continue;
        pre(p.fi,u);
        n_sub[u]+=n_sub[p.fi];
        for(int i=0;i<p.se;i++) cnt[u][k-p.se]+=cnt[p.fi][i];
        for(int i=p.se;i<=k;i++) cnt[u][i-p.se]+=cnt[p.fi][i];
    }
}

void adjust(int u, int pai, int rep){
    for(pii p : v[u]){
        if(blocked[p.fi]||p.fi==pai) continue;
        adjust(p.fi,u,rep);
        for(int i=0;i<p.se;i++){
            // cerr << "summing " << (ttt-n_sub[rep]) << ' ' << cnt[p.fi][i] << " on " << p.fi  << '\n';
            resp[p.fi]+=(ttt-n_sub[rep]+1)*cnt[p.fi][i];
        }
    }
}

void calc(int u){ // vamos mergear todos os vizinhos de x =)
    // cerr << "calc " << u << '\n';
    cnt[u][k]=1; ttt=0;
    for(pii p : v[u]) cost[p.fi]=p.se;
    for(pii p : v[u]){
        if(blocked[p.fi]) continue;
        // cerr << "start: " << p.fi << '\n';
        pre(p.fi,p.fi);
    }
    for(pii p : v[u]){
        if(blocked[p.fi]) continue;
        for(int i=0;i<p.se;i++){
            resp[p.fi]+=cnt[p.fi][i]*(ttt-n_sub[p.fi]+1);
            cnt[u][k-p.se]+=cnt[p.fi][i];
        }
        for(int i=p.se;i<=k;i++) cnt[u][i-p.se]+=cnt[p.fi][i];
        adjust(p.fi,u,p.fi);
    }

    // cerr << "just checking resp: ";
    // for(int i=0;i<9;i++) cerr << resp[i] << ' ';
    // cerr << '\n';

    for(pii p : v[u]){
        if(blocked[p.fi]) continue;
        for(int i=0;i<=k;i++) special[i]=cnt[u][i];

        // cerr << "before go " << p.fi << '\n';
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';

        for(int i=0;i<p.se;i++) special[k-p.se]-=cnt[p.fi][i];
        for(int i=p.se;i<=k;i++) special[i-p.se]-=cnt[p.fi][i];

        // cerr << "go " << p.fi << '\n';
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';

        for(int i=0;i<p.se;i++) resp[u]+=special[i]*n_sub[p.fi];
        int aux[11]; memset(aux,0,sizeof(aux));
        for(int i=0;i<p.se;i++) aux[k-p.se]+=special[i];
        for(int i=p.se;i<=k;i++) aux[i-p.se]+=special[i];
        for(int i=0;i<=k;i++) special[i]=aux[i];

        // cerr << "just go " << p.fi << '\n';
        // cerr << "special: ";
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';

        go(p.fi,u);


        // cerr << "just checking resp: ";
        // for(int i=0;i<9;i++) cerr << resp[i] << ' ';
        // cerr << '\n';
    }
    // cerr << "finish " << u << '\n';
    // cerr << "resp: ";
    // for(int i=0;i<9;i++) cerr << resp[i] << ' ';
    // cerr << '\n';
    blocked[u]=0;
}

signed main(){
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int n; cin >> n >> k;
    for(int i=1;i<n;i++){
        int a, b, c; cin >> a >> b >> c;
        v[a].push_back({b,c});
        v[b].push_back({a,c});
    }
    vector<int>roots=cd_decomp(n);
    reverse(roots.begin(),roots.end());
    for(int i=0;i<n;i++) blocked[i]=1;
    for(int x : roots){
        M++;
        calc(x);
    }
    for(int i=0;i<n;i++) cout << resp[i] << '\n';
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…